Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use layoutSubview in iOS

Tags:

ios

iphone

ipad

I am writing iOS application for iPad that require custom layout.

The layout from portrait and landscape are totally difference, so it can't be solve by using UIAutoResizingMask.

I try to use the layoutSubview Method, but I detected that layout subview is called a lot (from UIScrollView). How can i reduce the layoutSubview call to optimize the code , or I should call it by my self when ever the device is rotated.

Thank.

like image 790
Isara Rungvitayakul Avatar asked Aug 05 '11 08:08

Isara Rungvitayakul


People also ask

When should I call layoutSubviews?

layoutSubviews() The system calls this method whenever it needs to recalculate the frames of views, so you should override it when you want to set frames and specify positioning and sizing. However, you should never call this explicitly when your view hierarchy requires a layout refresh.

What is the use of auto Layout?

Auto layout is a property you can add to frames and components. It lets you create designs that grow to fill or shrink to fit, and reflow as their contents change. This is great when you need to add new layers, accommodate longer text strings, or maintain alignment as your designs evolve.

What is auto Layout in iOS?

Auto Layout defines your user interface using a series of constraints. Constraints typically represent a relationship between two views. Auto Layout then calculates the size and location of each view based on these constraints. This produces layouts that dynamically respond to both internal and external changes.

What is auto Layout in iOS Swift?

Auto Layout constraints allow us to create views that dynamically adjust to different size classes and positions. The constraints will make sure that your views adjust to any size changes without having to manually update frames or positions.


2 Answers

For different landscape and portrait design use view controllers methods such as

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;

If you create your custom view depending on current orientation, check this orientation by UIDeviceOrientationDidChangeNotification notification and write appropriate code.

in one of the init~ methods:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangedOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil];

And action

- (void) didChangedOrientation:(NSNotification *)sender{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (UIDeviceOrientationIsPortrait(orientation)){}}
like image 107
beryllium Avatar answered Sep 20 '22 04:09

beryllium


The fact that layoutSubviews gets called by a child UIScrollView is very unfortunate, but there's an (ugly) workaround:

@interface MyClass : UIView {
    BOOL reallyNeedsLayout_;
}
@end

@implementation MyClass

- (void)setNeedsLayout
{
    [super setNeedLayout];
    reallyNeedsLayout_ = YES;
}

- (void)setFrame:(CGRect)rect
{
    [super setFrame:rect];
    reallyNeedsLayout_ = YES;
}

- (void)layoutSubviews
{
    if (!reallyNeedsLayout_) return;
    reallyNeedsLayout_ = NO;

    // Do layouting.
}
@end

Not the best solution but seems to work reasonably well.

like image 38
DarkDust Avatar answered Sep 17 '22 04:09

DarkDust