My application has a tab bar, and in one tab I have a navigation controller.
I want to find the position of the center of the view that appears between the navigation bar and tab bar, so that I can display a UIActivityIndicatorView right in the middle of the view when stuff happens.
However, I'm getting different values of self.view.bounds.size depending on where I am in the navigation hierarchy. At the top level, it tells me 320x460 but it's 320x367 in deeper levels.
320x367 is the size I'm expecting (and confirmed in IB by the size inspector). So why am I seeing different on the top level only?
Answering own question by approaching the original problem a different way.
I was trying to create a UIActivityIndicator using initWithFrame, passing it coordinates for the center of the current view, calculated from its bounds.
However, this is unnecessarily complicated. I can simply set
activityIndicator.center = self.view.center;
to align the activity indicator right in the middle of the main view.
Related
In iOS13, the default way when presenting a view controller was changed to the "sheets/cards" view. As I’m not using auto layout (why not, is not really important and relevant), I rely on getting position of elements based on the frame of the view.
Now, the problem with the new method is, that the view frame doesn’t really reflect the actual content size visible on the screen anymore. E.g. if I have positioned a UIButton at the bottom on the view controller based on the view.frame bottom coordinate, it will be now cut off, as the view is actually moved down in the amount of the nice "sheets/cards" visual indication at the top. The same problem is even more evident in an iPad, where centring another view in the view controllers view will be offset, due to the fact that the default presentation style is now a "sheet" in the middle of the screen.
I’ve currently changed everything to force the full screen version, but it would be nice to use the new fancy design.
Anybody has any idea how to get the actual visible rect/coordinates in the new style without changing things to auto layout?
Here are how they look. The "flower" is centered in the view and the X button should not be so close to the bottom or missing completely in the iPad version.
Finally figured it out. As I was setting the positions of items in viewDidLoad, the frame was not calculated correctly, thus resulting things being laid out incorrectly. When resetting the frame and positions in viewDidLoadSubviews, the positions were placed correctly.
I have been battling this transition animation and I am pretty much out of ideas. I am attempting something similar to going from the collection to the individual photos in the Photos app on iOS.
It all works to my satisfaction with the exception that the frame for the "big" detail view of the image is not correct. It is the right size but it is about 87 points closer to the top of the screen compared to the actual position of the image in the final state. This is pretty much the same height as what is above the "safe area" (iPhone X titles + navItem) and irritatingly close to what is also below the safe area (toolbar and iPhone X home area).
I have Googled (and "SO'd") a bunch of different solutions to similar sounding problems. E.g: UIViewControllerAnimatedTransitioning with Safe Area Insets on iPhone X
I have downloaded and perused example code from Github. E.g: https://github.com/SamStone92/CustomTransitions
It seems to me that I have something in my view (controller) hierarchy which is complicating this more than most. I would love some hints as to what might be causing the problem and how I might go about fixing it.
My hierarchy is:
NavigationController containing the root VC with a UICollectionView.
Tapping a cell transitions to a UIPageViewController for a "detail view" where I can page between items in the collection.
UIPageViewController has a bottom toolbar in addition to the navigation bar.
The content ViewController has a ScrollView with a UIImageView in it to get some zooming.
Seems like the common approach is to add the destination view to the container, force a layout pass and then get the frame. I have tried many variants of this with and without converting the coordinates. (they appear to always remain the same before and after conversion)
My Theory
I am leaning towards the UIPageViewController being the complicating factor. But I have not been able to untangle how to get the correct coordinates.
The destination view (in the animation) is not the content view but the PageVC view which in turn may or may not have added the content view, adapted it to the navigation item or the toolbar.
Seems like viewWillAppear on the content VC does not have the right coordinates. I can tell that the detail content view is getting a call to viewWillLayoutSubviews after that and also after all the animation delegation stuff has had its turn.
This is a color overlay of my main views. Grey is the top and bottom areas outside the safe area. Blue is where the transition animates to before revealing the green, underlying actual position it should have animated to.
I have nested a navigation controller inside another and now its causing the uiview inside the nested navigationcontroller to resized weirdly.
Here are a few screen shots to show you whats going on.
This is with both navigation bars showing, as you can see the bottom extends further than the physical screen can allow.
this one only shows the sub navbar with the main nav bar hidden.. as you can see there is this weird space above the subbar that looks like the height of a status bar. i'm not sure what it is.
Lastly this shows only the mainnavbar being shown and the subbar being hidden..
the last view is what I would like to use, However.. if you look at the bottom of the view its only got a portion of the A's displaying.. however if you look to the view in InterfaceBuilder on the left you will see that interface there should be more letters there but strangely the view is not resizing to fit in the bound of the physical view...
I am wondering hopefully with the detail supplied if you can tell me how to get the view to resize correctly and fit everything in properly.. any help would be greatly appreciated.
I think you set the autoresizeMask property = UIViewAutoresizingFlexibleBottomMargin for these UILabel objects, you'll get the last UILabel aligned to the bottom of your UIView.
Once again, I'm almost entirely sure this is something dumb that I'm doing, but I've been banging my head against this one for hours & am getting nowhere.
I'm trying to restructure the view hierarchy of my app. I need to be able to detect user interface orientation changes globally in order to correctly rotate a "Loading" view displayed when the app is downloading content. (device orientation changes seem to fire at different times, causing the view that needs to respond to these events to rotate sporadically).
The app previously added a UINavigationController's view to the main window. I modified the hierarchy to add the view of a UIViewController subclass to the main window, and added the view of the UINavigationController to the subclass's view. The UIViewController subclass manages the display & rotation of the "Loading" subview, and I was expecting the rest of the app to continue behaving normally, as inserting one extra empty view into the hierarchy didn't feel like I was changing too much.
My initial problem was the positioning of the UINavigationController - it was 20 pixels too low, resulting in a gap between the status bar and the navigation bar, and cutting off the bottom 20 pixels of the tab bar. I was able to adjust this by setting the frame property of the UINavigationController's view to the bounds property of the UIViewController's view, which corrected the position.
However, now I'm stuck with a 20-pixel-high dark "overlay" on top of my navigation bar. If I were to guess, I'd say it was black with 50% opacity. Touch events on this bar don't work (e.g. if I try to tap the "Back" button through the overlay, nothing happens). The fact that the height is equal to that of the status bar hasn't escaped me, but I'm at a total loss as to what could be causing it.
I hate feeling this stupid, so if anyone has any insight into this problem, you'd really make my day. Thanks in advance!
OK, a few things pop out from your post.
My initial problem was the positioning of the
UINavigationController - it was 20
pixels too low
This makes me believe it is related to your new problem.
I was able to adjust this by setting
the frame property of the
UINavigationController's view to the
bounds property of the
UIViewController's view
This sounds like the view it was loaded onto was offset 20 pixels, and when you set it to the bounds, it repositioned it on the windows view space.
Touch events on this bar don't work
(e.g. if I try to tap the "Back"
button through the overlay, nothing
happens)
This is the big thing. If touch events aren't being sent to the view, then what that means is that the OS doesn't see a view where you are pressing (or rather the view you want it to), so that view doesn't get the message to do something.
From what you have said, I believe your problem is with your base view controller that you just added. Try redoing the frame on, making it conform to where you want. Then take out the code you put in to set the navigation controllers frame. The navigation controller should fit to the view you added too, and once you have that main view where it needs to be (20 pixels higher apparently), then everything should work.
My view doesn't stretch to fit the current orientation!
I am creating a tab bar application. I replicated the sample one that you create when you "create a new tab bar application". Everything works except when I change the orientation of the iPad it rotates the view, the tab bar stretches out on the bottom, but the view doesn't resize. Basically if you start in landscape then rotate to portrait, it rotates but the view is still landscape shape even though it rotates.
My tab bar has two tabs (just like the sample application) and so I compared mine against the sample which works property by property. One difference is I noticed my FirstView in IB under the resizing area doesn't show the resize arrows left/right up/down. In other words it isn't marked to auto fill its container. The sample's FirstView and SecondView DO have these arrows. But I can't turn them on!
I even tried creating a fresh new view but I still can't press these arrows on. what am I doing wrong here?'
Thanks a lot.
The solution is this:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Do this in viewDidLoad. There must be a bug in IB.
Another answer is turning off any simulated tabbars, nav bars, or status bars on the view in Interface Builder. Go into the autosizing area and turn on the auto grow arrows. Then turn back on the simulated user elements.