Width of Modal Sheet on iPad - objective-c

I am presenting an instance of UINavigationController modally with the modalPresentationStyle set to UIModalPresentationFormSheet. Inside the UINavigationController is an UITableViewController. For a delete button in the table view, I have to know the width of the sheet. Is there any way to access this?
I tried [self.view bounds], however this returns the with of the screen. I think that's because the view is not visible at the time a call this, however I don't know where else I should call it.

You can directly measure and store a magic value for the form sheet width (not pretty, I know, but it works) the value that I have been using is 540.
If you really want to get it programatically. You'll have to make sure that the view has been resized and prepped for presentation before taking the bounds value from the view. I believe this happens somewhere between viewWillAppear and viewDidAppear, although I can't remember exactly.
If all you want to do is ensure a button is aligned to the right, try using the autoresizingMask property of the button. I believe you'll only need to use UIViewAutoresizingFlexibleLeftMargin.

You can do "last minute" view setup and adjustments in viewDidLoad -- all the nib outlets have been initialized by that time.

Related

ios7 custom VC Transition: Overlap a Modal Form Sheet View

i want to use the new UIVC Custom Transition API in my iPad App Project. And i despair of it -.-. what i want to do, sounds very simple at first. My "FirstViewController" (simply the names) is a normal FullScreenVC. From that VC i open a "SecondViewController"modally with the default Presentation style Form Sheet. Everything allright. The SecondViewController is a normal UiTableViewController. So from inside the SecondViewController I want to open a "ThirdViewController" modally as well with a custom transition. This ThridViewController have to overlap the SecondVC with the Form Sheet Presentation and the content of the second view controller have to be dimmed as well. But i get many problems inside the animateTransition-method in the the Transition Delegate. My best idea by now is, making a UIView Snapshot of the from View. Create a new UIView with black background and alpha 0.5 and put it as a subview inside UIView Snapshot. Then transfer the frame and the center of the fromView to the toView and add the UIViewSnappshot as a subview to the toView and send it to the back. finally adding the toView to the containerView.
But when i do this, I get two s*** problems. The First is, that the Transition don't recognize that i am using a Retina display, because i put the center of the fromView to the the toView. But the toView dont overlap the fromView, better its nit at the same postion. Its almost at the left down of the screen and not in the middle of the screen. The second problem is, that the toView content seems to be transculent. In Storyboard and in code i write "be opaque and white bgcolor". But at runtime the see the controls of the view but the bgcolor is the bgcolor of the dimmed View behind it. Why?
At the moment i think i'm a dump guy :( What in hell im doing wrong?
Thanks
Avarlon

Xcode's auto layout is only effective in viewDidAppear and this is very problematic

After upgrading my project to iOS 6, I realized that auto layout is only effective in viewDidAppear and most of my code expects the view's frame to be available in viewDidLoad. This limitation renders the really nice auto layout feature almost useless for me. Is there any suggestions to help me use auto layout?
For example, sometimes the developer needs to adjust information about a subview based on where auto layout chooses to place that particular subview. The subview's final location cannot be ascertained by the developer until AFTER the user has already seen it. The user should not see these information adjustments but be presented the final results all at once.
More specifically: What if I want to change an image in a view based on where auto-layout places that view? I cannot query that location and then change the image without the user seeing that happen.
As a general rule, the views frame/bounds should never be relied on in viewDidLoad.
The viewDidLoad method only gets called once the view has been created either programmatically or via a .nib/.xib file. At this point, the view has not been setup, only loaded into memory.
You should always do your view layout in either viewWillAppear or viewDidAppear as these methods are called once the view has been prepared for presentation.
As a test, if you simply NSLog(#"frame: %#", NSStringFromCGRect(self.view.frame)); in both your viewDidLoad and viewWillAppear methods, you will see that only the latter method returns the actual view size in relation to any other elements wrapped around your view (such as UINavigationBar and UITabBar).
As told by #charshep in a comment, calling view.layoutIfNeeded() in viewWillAppear can do the trick.
Quote of his original comment
I had trouble getting a table view to appear at the correct scroll position when pushing it [...] because layout wasn't occurring until after viewWillAppear. That meant the scroll calculation was occurring before the correct size was set so the result was off. What worked for me was calling layoutIfNeeded followed by the code to set the scroll position in viewWillAppear.

Confusing behavior from UIPopoverController

I'm trying to set up a popover to appear that displays a UIDatePicker when I press a button, however I'm getting some very confusing behavior. I created a view controller that housed nothing but the UIDatePicker, wired one up in the class i needed it in, and added it to a new UIPopoverController like this:
self.timePickerPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.timePickerViewController];
then I present it like so:
[timePickerPopoverController presentPopoverFromRect:prepTimeButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
(prepTimeButton being the button that was pressed). However, I just get the following result:
Instead of it displaying next to the button that was pressed and at the target size (it's way too tall right now; should only be the size of the date picker). I also tried giving it a custom view of the proper location and size in which to display, but that didn't help much (just shifted the popover to the right half of the screen). What am I doing wrong and how do I fix it?
Is self.view the direct superview of prepTimeButton? Perhaps prepTimeButton is nested in a subview, in that case you'd need to use that as the inView: parameter (or convert the coordinates).
Did you set the contentSizeForViewInPopover property of your view controller?
Make sure to set both contentSizeForViewInPopover on the internal view controller and popoverContentSize on the UIPopoverController itself.

Objective C: Can I set a subview to be firstResponder?

I have a situation whereby I am adding a view from another viewcontroller to an existing viewcontroller. For example:
//set up loading page
self.myLoadingPage = [[LoadingPageViewController alloc]init ];
self.myLoadingPage.view.frame = self.view.bounds;
self.myLoadingPage.view.hidden = YES;
[self.view addSubview:self.myLoadingPage.view];
Is it possible to set 'self.myLoadingPage' to be the first responder? This is the case whereby the loadingpage view size does not cover the entire size of the existing view and users can still interact with the superview (which is not the desired behaviour). I want to just enable the subview in this case.
When I had a similar problem, I made an invisible UIView that covered the entire screen, I added the large invisible UIView on top of the main view and made the loading view a subview of the invisible UIView.
The simplest solution is to override hitTest method in your loading view to return TRUE. This top view is first in the responder chain, the hitTest method gets called which NORMALLY returns TRUE if the point is within the view and will therefore be handled, returning TRUE regardless means you get the touch event and effectively block the message being resent to the next responder.
Interesting question. I found a similar post with a quote from the Apple Developer Forums on this issue:
To truly make this view the only thing
on screen that can receive touches
you'd need to either add another view
over top of everything else to catch
the rest of the touches, or subclass a
view somewhere in your hierarchy (or
your UIWindow itself) and override
hitTest:withEvent: to always return
your text view when it's visible, or
to return nil for touches not in your
text view.
This would seem to indicate there isn't a terribly straightforward solution (unless there was an API change regarding this made after October, 2010.)
Alternatively, I suppose you could go through all the other subviews in your superview and individually set their userInteractionEnabled properties to NO (but that would probably prove more cumbersome than the quoted solutions).
I would love to see other ways to allow this.

Adjust UIPopoverController position after resize

I have a UIPopoverController containing a UITableView. The popover is resized in its view controller's -viewDidAppear function to fit the contents of the table. While the popover resizes properly, its arrow is usually no longer pointing at the original CGRect. Is there a way to force the popover to reposition itself after a resize so that its arrow is pointing at its intended target?
EDIT: I can't set the size of the popover in -viewDidLoad since the table view does not load its data until -viewDidAppear is called, and as a result I do not know what size the popover should be until then. In addition, I resize the popover when one of the table view cells is clicked to display another view and this also results in the arrow no longer pointing at its intended target.
I think this may be the wrong way to go about it, since you're having to re-do the built-in behaviour that positions the arrow to begin with.
I don't resize popover content in viewDidAppear. I set the contentSizeForViewInPopover property in the view controller's viewDidLoad method, e.g.:
- (void)viewDidLoad
{
[super viewDidLoad];
self.contentSizeForViewInPopover = CGSizeMake(320, 155); // sized for a 3-row UITableView
}
(Quick warning: if you're developing a universal app, this code will cause a run-time crash on devices running 3.1.x and below.)
You can also set the content size for the popover controller before you present it, which should take care of your problem. Check out the popoverContentSize property.
According to this answer, you can call presentPopoverFromRect:inView: on the popover again and it will reposition the arrow. I haven't tested this myself.