self.view not within visible coordinates - ios

I'm going through someone's code trying to determine why their storyboard goes out of control on orientation flips..
Modal segues are going from View Controller to another View Controller. The segue identifier is being defined and called correctly:
self performSegueWithIdentifier:#"identifiername" sender:self];
if the orientation is standard.. self.view.frame.origin.x and y are 0,0. If you flip it to landscape.. you get -20, 1280? Nothing is defined programmaticly using CGRects and all standard Orientations return true with no changes.
Does anyone have any ideas whatsoever???

I would look through the project for any odd calls to setFrame: obviously. But also, for self.view.transform =, applied transforms (like zooming with a transform) affect frame. You can also check your bounds, I suspect the bounds of your view are correct, but checking never hurts.
Also you can easily log a CGRect like this:
NSLog(#"%#",NSStringFromCGRect(self.view.bounds));
Good hunting.

Related

Finding a CGRect in a complex view hierarchy

I am using a coachmarks/wizard framework called WSCoachMarksView that darkens your entire screen, and lets you create a highlighted area within a given CGRect to illuminate a call to action. I have a somewhat complicated hierarchy of views, and was having trouble properly identifying the CGRect I want to highlight with respect to the parent windows.
Here is my hierarchy. The goal is to find the CGRect for Day1, which is an imageview of about 50 pixels in height, and 25 pixels in width.
-TabViewController
-NavigationViewController
-HomeViewController : ViewController
-Container View (container within homeviewcontroller)
====================Everything below is within this container==============
-
HomeContainerViewController : ViewController (this view is loaded within the container)
-WeekViewController: ViewController
DayView (just a view I dragged onto WeekViewController to hold subviews)
Day1 (this is a rectangle imageview within the above DayView)
So there is a containerview within HomeViewController. Based on the above hierarchy, I've tried a multitude of permutations to correctly highlight Day1, but all have failed. I think my understanding of convertPoint is wrong and wanted to ask for some help in understanding which parameters to pass.
I read somewhere that you can only work off of the relationship between the parent/child but not a grandparent, etc?
Given this:
//assume tabViewController is the TabViewController above
//assume weekViewController is self.view, or WeekViewController
let day1Point = weekViewController.view.convertPoint(day1.frame.origin, fromView: tabViewController.view)
So unfortunately something like this just highlights the area on the top-left of the screen (my day 1 is actually near the middle of the screen).
What's the approach for convertPoint or convertRect? Is it always the leaf node in the hierarchy tree, and the "fromView" parameter is the top-most view (parent node)?
Thanks so much, any clarification / suggestions would be very much appreciated!
edit
so something like this gets me closer:
var myFrame: CGRect = dayView.convertRect(day1.frame, toView: self.view)
but it's still off slightly depending upon iPhone 5, 5s, 6, 6plus (only part of the image appears).
Note by OP:
Fogmeister suggested in the comments to use viewWillAppear, but i'm sure he meant viewDidAppear (which is actually what led me to solve this problem). other than that, everything he suggested was spot on (i.e. the correct usage of convertPoint/Rect below). Thanks so much for your help!
Well, the way convert works is that it will take the absolute point and convert it to different reference views.
So you should be able to do something like this...
From the WeekViewController you should be able to do...
self.view.convertPoint(day1.frame.origin, toView:homeViewController.view)
or...
self.view.convertRect(day1.frame, toView:homeViewController.view)
You will need a reference to the homeViewController to do this. I',m not certain what you're trying to do though. Where is your code that is highlighting the view? Is that code in homeViewController?

UIView not redrawing, but elements become misplaced

I'm having an issue with my app's layout which is a bit tricky to explain. When the app first starts, this is what I'm showing:
After the user taps "Create Profile", I animate those buttons and show a registration form instead:
Needless to say, the buttons are now not in their "natural" position. Note, however, that the text fields are - that's where I have placed them in the storyboard, but when the view first loads I hide them. The animations are working great, but then I needed to scroll my view up when the user gives focus to a text field and the keyboard hides the field. The details of how to trigger the bug are a bit hard to explain, so I managed to boil it down to what seems to be a redraw event, except that it isn't... Let me try and explain that.
First of all, here's what happens when the keyboard is about to show:
- (void)keyboardWillShow:(NSNotification*)notification
{
CGRect frame = self.view.frame;
frame.size.height -= 1;
self.view.frame = frame;
}
Notice that this is a test only, probably the minimal I found that would still trigger the bug. All it does is resize the view. I would expect the view to be exactly as it was, with one less pixel, right? Wrong. Here's what I get:
That is, all elements returned to their "natural" positions, completely ignoring their previous positions. My first guess was that it would seem that the window is redrawing, so I tried this:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
NSLog(#"View was drawn");
}
But this only triggers when the window is first drawn, not when this strange behaviour happens. To understand what I mean by "natural position", here's what I have in storyboard:
You can also see that I'm not using constraints and the underlying structure of my view:
The full code for the entire setup is quite extensive, so pretty much not practical at all to show. However, how I animate the subviews resumes to changing their frame as I did in keyboardWillShow, and setting their positions to whatever I need.
Any ideas?
So you're using storyboards and you have "Use AutoLayout" set to false for your entire storyboard?
In that case your app is using "struts and springs" style placement rules. You're going to have to debug those.
It's a bit hard to describe everything in a view controller in a post. It's easier to go over it in IB. Perhaps you can write a utility function that logs all the autoresizingMask values for the views in your view controller, and go over those, and perhaps post them here describing the autoresizingMask values for each view in your original post.

UIButton doesn't work after rotate to landscape

The following is a snippet of the code being used to set up the subview layout on device rotate (I am using the same code for initial setup of the views):
(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if(screenBounds.size.height >= 1024) {
[myButton setFrame:CGRectMake((screenBounds.size.width/3), (screenBounds.size.height/100)*81, (screenBounds.size.width/3), (screenBounds.size.height/100)*16)];
}
else {
[myButton setFrame:CGRectMake((screenBounds.size.width/3), (screenBounds.size.height/100)*81, (screenBounds.size.width/3), (screenBounds.size.height/100)*16)];
}
}
What is happening is myButton is being redrawn properly, but trying to interact with the button does nothing. If I go back to portrait, the button is able to be pressed after redraw. If I start in landscape, the button works; but if I later rotate away and then back to landscape, button no longer works. This has me stumped.
So, it's very difficult to tell what's going on in your view without being able to see your storyboard, view hierarchy, etc. However, Xcode has made troubleshooting these types of issues much easier with Live View Debugging.
The first thing you can try is turning on view frames. This will allow you to see the frames and bounds for each control. Most likely what you will see is that your button's frame is in one place, but the bounds is someplace else. You can turn on view frames via Debug -> View Debugging -> Show View Frames.
If you need a more comprehensive overview of your hierarchy -- for example, maybe another view is covering the button -- Xcode now has a really cool feature to capture the view hierarchy. You can manipulate the hierarchy in 3D, filter for certain controls and more. This will allow you to visually inspect the hierarchy at run-time and see what might be going wrong with your button. Debug -> View Debugging -> Capture View Hierarchy.

Get width and height of container from view

Forgive me if this is a duplicate. I thought for sure this would be an obvious question.
I have a container in a storyboard, which is of class ModelViewController (the whole view controller). From ModelViewController I need to get the width and height of the container. I am currently trying:
self.view.bounds.size
Which yields 0.563380 and 0.000000. I also tried
self.view.frame.size
Which yields the dimensions of the entire screen. What am I missing here?
From this post
View frames are not actually useable in viewDidLoad; you should move all of your geometry-manipulating code into viewWillAppear. The system will clobber any changes you set in viewDidLoad between there and when it's about tom come on screen.
And the comment
Actually, you should move geometry changes to -viewDidAppear pre-iOS 5 and to -viewWillLayoutSubviews for iOS 5+. -viewWillAppear: may not actually have the correct bounds/orientation if the view is being animated.
I found the solution. The correct dimensions are indeed given when called from viewWillLayoutSubviews. I was calling from viewDidLoad giving incorrect results.

Bounds of custom UIView not correct during awakeFromNib - when are they set?

I have a custom UIView, which I have placed using Xcode (4). I need to set some default state, based on the actual bounds of the view. During awakeFromNib, bounds seems to be returning the size of the view in the storyboard layout in Xcode.
The view is in the detail side of a UISplitViewController, which in Xcode is the size of a full portrait iPad screen, but if the app loads in landscape mode then, via springs-and-struts, its size is changed, but this appears to happen after awakeFromNib.
Should I be setting this state in some other method?
It depends what sort of state you are setting - if it is dependent on the bounds then you'll need to reset it every time the device is rotated, presumably? In that case overriding setFrame: might be a better bet - be sure to call the superclass implementation before you do anything else, though.
The answer is was probably looking for, or at least the solution I have used, is to provide a public method in the UIView to be called by the parent UIViewController in viewWillAppear:

Resources