iOS 10 iMessage app extension: how do i calculate

2019-01-21 23:01发布

问题:

I downloaded the Xcode 8 beta and was trying to play around with the iMessages app extension sdk but ran into an issue with their seemingly nonstandard nav bar height

when i transition into the app's expanded view, my image with the following frame CGRect(x: 0, y: 0, width: 100, height: 100) ends up partially hidden behind the nav bar. i would like it to appear below the nav bar.

i tried self.navigationController?.navigationBar.isTranslucent = false but it didn't work, which i guess makes sense since it's out of my app's scope to control.

has anyone played around with this yet? i want to avoid 2 things. simply guessing the appropriate height and moving away from a programmatic solution. thanks for the help

回答1:

It may help to have a constraint with the top layout guide like so:

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true


回答2:

You can get the height from controller's layout guide:

self.topLayoutGuide.length

The reason why @Dilts's demo works is because the labels' top are constraint to the top layout guide. If they are constraint to the superview, then it will also go behind the bar.



回答3:

If you are like me and still find Auto Layout hard to use, then you can use the viewDidLayoutSubviews method to automatically adjust the view size. I have a table view with the same issue as you, so I used this simple method to change the table view's top side content inset:

-(void)viewDidLayoutSubviews {
    [self.tableView setContentInset:UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0)];
}

So far it works fine (in both portrait and landscape) on all iDevices.



回答4:

To answer your question: "what is the height of the extra tall navbar":

It's 86px.

UPDATE

About the Navbar hiding your UI. I did a quick demo and I had no problems.

I added a couple of labels to the top of the view (just under the status bar, at y-point value 20). Next I added 2 constraints: Leading space and Top Space for the left label and Trailing space and Top Space for the right label.

This was my result, both in compact mode and also expanded. So just make sure you put your components below y-point-value 20 and have some constraints, that way Apple will hand the view resizing for you!



回答5:

If you set the top layout guide as the top constraint, it works for MSMessagesAppViewController. But it will not work on UIViewControllers, because the layout guides are different.

Unless you really need to use a UIViewController class for some reason (example: MessagesAppViewControllers have trouble containing Obj C++ code), stick to MSMessagesAppViewController.



回答6:

This is accepted answer in Objective-C

[view.topAnchor constraintEqualToAnchor:[self.topLayoutGuide bottomAnchor]].active = YES;


回答7:

As of now with Xcode 8.2, none of the above solution works for me. @Dilts answer will works only for MessageViewController, which inherits from MSMessagesAppViewController. But when we try to do same with our ViewController, which inherit from UIViewController, then this will not work.

I have do this by binding Top Constraint with respect to view rather than Top Layout guide. I set top constraint to zero with respect to view and bind that constraint as topLayout.

@IBOutlet weak var topLayout: NSLayoutConstraint!

And then change value of constraint programatically on changing of presentation style.

override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
        // Called before the extension transitions to a new presentation style.

        if presentationStyle == .compact{
            mediaViewController?.topLayout.constant = 0.0
        }else{

            mediaViewController?.topLayout.constant = 86.0
        }

    }

Compact Mode

Expanded Mode



回答8:

    [self.view addConstraints: [NSArray arrayWithObjects:

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeTop
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.topLayoutGuide
                                                         attribute:NSLayoutAttributeBottom
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeBottom
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.bottomLayoutGuide
                                                         attribute:NSLayoutAttributeTop
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeLeft
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:[self view]
                                                         attribute:NSLayoutAttributeLeft
                                                        multiplier:1.0
                                                          constant:0.0],

                            [NSLayoutConstraint constraintWithItem:YourViewHere
                                                         attribute:NSLayoutAttributeRight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:[self view]
                                                         attribute:NSLayoutAttributeRight
                                                        multiplier:1.0
                                                          constant:0.0], nil]];