Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C : How to create self.view inside Safe Area programmatically

I have just changed my app from supporting iOS 8 and up to supporting iOS 9 and up.

Since I don't use storyboards to create my views, I was wondering if there's the "Use Safe Area Guides" option programmatically or something like that.

I've tried to anchor my view but they keep overlapping the top & bottom in the iPhone X simulator.

like image 877
Ravindhiran Avatar asked Nov 02 '17 12:11

Ravindhiran


2 Answers

Try this in Objective-C and see:

UIView * myView = // initialize view using IBOutlet or programtically

myView.backgroundColor = [UIColor redColor];
myView.translatesAutoresizingMaskIntoConstraints = NO;

if (@available(iOS 11, *)) {
    UILayoutGuide * guide = self.view.safeAreaLayoutGuide;
    [myView.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
    [myView.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
    [myView.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
    [myView.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;
} else {
    UILayoutGuide *margins = self.view.layoutMarginsGuide;
    [myView.leadingAnchor constraintEqualToAnchor:margins.leadingAnchor].active = YES;
    [myView.trailingAnchor constraintEqualToAnchor:margins.trailingAnchor].active = YES;
    [myView.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].active = YES;
    [myView.bottomAnchor constraintEqualToAnchor:self.bottomLayoutGuide.topAnchor].active = YES;

}

// Refresh myView and/or main view
[self.view layoutIfNeeded];
//[self.myView layoutIfNeeded];

Ref from: Use Safe Area Layout programmatically - Swift

Result:

enter image description here

like image 172
Krunal Avatar answered Sep 20 '22 15:09

Krunal


You can find top and bottom padding programmatically. I think this will solve your issue.

if (@available(iOS 11.0, *)) {
        UIWindow *window = UIApplication.sharedApplication.keyWindow;
        CGFloat topPadding = window.safeAreaInsets.top;
        CGFloat bottomPadding = window.safeAreaInsets.bottom;
}

Edit: As mentioned in the comments (thanks, @albert-renshaw), the object can't be drawn from viewDidLoad on the first run as UIWindow won't be accessible until after at least one run loop. To bypass this you can do it several ways:

1. Simply move your viewDidLoad code into a new method postViewDidLoad and use:

[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f];

...in the original viewDidLoad method, then UIWindow will be accessible.

OR

2. Enclose creation of your object in

dispatch_async(dispatch_get_main_queue(), ^{
// your code here...
});
like image 24
user6788419 Avatar answered Sep 18 '22 15:09

user6788419