简体   繁体   中英

change subviews according to its superview frame

I have a custom UIView class

CustomView.m

- (instancetype)initWithString:(NSString *)aString {
    self = [super init];
    if (!self)
        return nil;
    [self setAutoresizesSubviews:YES];
    UILabel *label = [[UILabel alloc] init];
    label.frame = ({
        CGRect frame = self.frame;
        frame.origin.x = CGRectGetMinX(frame) + 50;
        frame.origin.y = CGRectGetMinY(frame) + 20;
        frame.size.width = CGRectGetWidth(frame) - 100;
        frame.size.height = CGRectGetHeight(frame) - 40;
        frame;
    });
    [label setText:aString];

    [self addSubview:label];
    return self;
}

ViewController.m

-(void)addCustomView {
    CustomView *custom = [CustomView alloc] initWithString:@"abc"];
    custom.frame = ({
            CGRect frame = self.view.frame;
            frame.origin.y = CGRectGetHeight(frame) - 100;
            frame.size.height = 100;
            frame;
        });
    [self.view addSubview: custom];
}

Here's the problem, I set frame of my CustomView after alloc init it. Which means its frame is CGRectZero before I change it.

Therefore, the frame of UILabel is zero, too.

How can I change frame of my subviews after their superview's frame changed ? Like above.

Thanks.

You simply need to implement -layoutSubviews in your CustomView , and do your subview layout/frame calculation stuff in there. -layoutSubviews will get called when your CustomView 's frame changes.

Edit for further clarification:

You could add a property for the label, or use a tag , so that you can access it it -layoutSubviews , something like this;

- (void)layoutSubviews
{
    self.label.frame = ({
        CGRect frame = self.frame;
        frame.origin.x = CGRectGetMinX(frame) + 50;
        frame.origin.y = CGRectGetMinY(frame) + 20;
        frame.size.width = CGRectGetWidth(frame) - 100;
        frame.size.height = CGRectGetHeight(frame) - 40;
        frame;
    });
}

Edit 2:

Of course, what you probably want to do as well is change your initialiser to include the frame, like so:

- (instancetype)initWithFrame:(CGRect)frame string:(NSString *)string
{
    self = [super initWithFrame:frame];
    if (self) {
        // Do some stuff
    }
    return self;
}

That way, your view's frame is set when you first create the label. Implementing -layoutSubviews is still a good idea though, for any future frame changes/orientation changes etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM