iOS 10 iMessage app extension: how do i calculate the height of the extra tall navbar
Asked Answered
K

8

21

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. compact expanded thanks for the help

Kora answered 17/6, 2016 at 16:30 Comment(8)
Is it possible to add constraints to the view? If possible, try add a vertical space constraint of -86.0 from the top margin.Extravehicular
i'm hoping to avoid using a constant to solve this issue. i'd much prefer to write something like calculating programmatically relative to the nav bar height.Kora
I've updated my answer with a mini demo on how to get you going with constraints that handle auto-resizing.Extravehicular
lol, you provided the 2 approaches i specifically said i wanted to avoid. but thanks for the pointers, i'll add some constraints and let you knowKora
If you don't add constraints, it will be hard to automatically handle resizing for different devices and also for the compact and expanded modes for each screen size. Your code will quickly become huge! It's a better practice to not hard code the value, instead let Apple handle the resizing for you using Auto Layout. You can read more about Adaptive User Interfaces here!Extravehicular
Anyone know of a way to cover them with your view? Apple does it with a UIImagePickerController from the text bar in iOS10 beta iMessage.Wrongdoing
You've probably added top constraint to superview. Add top constraint to topLayoutGuide instead. This solved exact same problem I had.Barquisimeto
Nothing works for me. Im using tableviewController and the cell starts under navbarJanettejaneva
A
15

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

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true
Abstergent answered 19/8, 2016 at 23:3 Comment(2)
@JosipB. is the accepted answer....!. But not works for me in objective c code. I'm using this equivalent [self.view.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor constant:8.0].active = YES; but apparently something is different.Janettejaneva
@Janettejaneva check my answer in ObjectiveCReactionary
Z
4

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.

Zizith answered 4/8, 2016 at 13:21 Comment(0)
D
4

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.

Downcast answered 20/9, 2016 at 13:35 Comment(0)
E
2

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

iMessage App Extension NavBar height

It's 86px.

UPDATE

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

Added labels At y position 20

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.

Result

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!

Extravehicular answered 17/6, 2016 at 17:19 Comment(5)
@Kora I also tried this with a UIImageView (with Clip Subviews enabled and Aspect Fill mode) with a few simple constraints, and again starting at y-point-value equal to 20 and it worked like a charm!Extravehicular
could you provide the project? I tried following your steps but its not working for me thanksBulletin
I'm constraining to top layout guide and still get hiddenGilbertgilberta
if you set top constraint to top layout guide, it will work from compact to expand mode. However, it won't work if a extension starts with expand mode.Embowed
@Dilts: This only works 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.Buff
D
1

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.

Dumps answered 20/9, 2016 at 4:55 Comment(0)
R
0

This is accepted answer in Objective-C

[view.topAnchor constraintEqualToAnchor:[self.topLayoutGuide bottomAnchor]].active = YES;
Reactionary answered 18/1, 2017 at 13:11 Comment(2)
You could verify that this works ?. Because do not do it. Can you helpe me here #41707659Janettejaneva
You can check my question and verify that I am doing wrong, pleaseJanettejaneva
B
0

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
        }

    }

enter image description here

Compact Mode

enter image description here

Expanded Mode

enter image description here

Buff answered 11/5, 2017 at 13:48 Comment(0)
C
0
    [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]];
Coaction answered 17/6, 2017 at 0:4 Comment(1)
works well for constraining to the expanded mode, for collapsed I just assign the self.view.frame to the frame of the view i'm placing into collapsed mode (minus some offsets I may use for tool bar), but I use multiple views based on the mode it's in, not sure if these constrains will work for collapsed view since the top layout guide remains at the top I think in collapsed viewCoaction

© 2022 - 2024 — McMap. All rights reserved.