Does anyone know of a way to load a view controller at a point other than the top. This would be similar to opening a web page part way down ie Go to Target
This is not a tableview or webview so the point is not to go to a specific row of the table or place in the webview. Rather it is a regular UIVIewController and the point is to go to a specific vertical point on the screen where there is some relevant content.
Thanks for any suggestions.
Edit: I ended up using the following, not as elegant as I was hoping, but adequate:
-(void) raiseView:(float) float {
CGRect contextRect = self.view.bounds;
float boundsY = contextRect.origin.y;
contextRect.origin.y=boundsY+float;
self.view.bounds = contextRect;
}
I recommend reading up further on controller based interface and how to best use the common practices to your advantage.
My suggestion would be to rely on the presentation styles available to aUIViewController. Here would be an example of presenting a view controller over the current view:
MyViewController *controller = [[MyViewController alloc] init];
controller.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[currentViewController presentViewController:controller animated:YES completion:^{
// Do whatever you need to here
}];
Then upon completion, you can do anything you need to for presenting your content. Here you can simply set the controllers view to be whatever frame you desire (with, in your terms, any top point you would like). This way you can present a VC to the user and display anything you need on top at the point relevant to the content on the previous view.
Happy coding!
Related
I'm trying to add a new subView to a page, such that everything but itself is greyed out. However, I'm calling it from within a subview of the screen. To get it out, I have to do the following :
[self.view.superview.superview.superview.superview addSubview:self.cardDialog.view];
As you can surmise, this is extremely bad code. How can I find the proper parent level and set it correctly?
If the view is part of the view hierarchy, use the window property.
UIView* topView = self.view.window;
Or if your view is not on screen yet, you can get the window indirectly through your app delegate
UIView* topView = [UIApplication sharedApplication].delegate.window;
Else, if your target is not the window, you can walk up the view hierarchy until you find the view you want:
UIView* topView = self.view;
while(topView.superview != nil){
topview = topView.superview;
if( /*topview is the one you were looking for*/ ){
break;
}
}
I've found myself on this situation once and I gave up. I decided to use a modalView instead with a cross disolve transition. Not only you avoid the problem you are having but it helps keeping things organized.
Lately I improved this aproach by grabing a snapshot of the parentVC and sending it to the modalView, then I apply a tint. The overall effect is exactly what you are looking for, I guess.
I've been asked to add a fully custom transition between two UIViewControllers and came up with this solution. It works, but I don't know if there's a better / more elegant way to do it.
By fully custom, I mean involving modifying the first view controller subviews (moving them, not only fading or whatever), being able to change the duration, etc.
I'd like to know two things :
Can this be broken up in any way ? Some problem I might have forgotten maybe ?
Do you think this is ugly ? If so, is there a better solution ?
As a few lines of code is better than a thousand words, here is a very simple example to get the idea :
// Considering that self.mainView is a direct subview of self.view
// with exact same bounds, and it contains all the subviews
DCSomeViewController *nextViewController = [DCSomeViewController new];
UIView *nextView = nextViewController.view;
// Add the next view in self.view, below self.mainView
[self.view addSubview:newView];
[self.view sendSubviewToBack:newView];
[UIView animateWithDuration:.75f animations:^{
// Do any animations on self.mainView, as nextView is behind, you can fade, send self.mainView to wherever you want, change its scale...
self.mainView.transform = CGAffineTransformMakeScale(0, 0);
} completion:^(BOOL finished) {
// Push the nextViewController, without animation
[self.navigationController pushViewController:vc animated:NO];
// Restore old
self.backgroundImageView.transform = CGAffineTransformIdentity;
}];
I've double checked a few things that I thought might get wrong :
After the push, the view hierarchy isn't broken, everything looks fine, self.view suffer any changes
When poping, nextView isn't in self.view any more.
Thanks for your opinions.
There are differents way to make a transition between ViewControllers. Your code works but you can implement a more official way.
Use methode transitionFromViewController:toViewController:
Check the tutorial : http://www.objc.io/issue-1/containment-view-controller.html#transitions
Or you can use UIViewControllerContextTransitioning Check the tutorials : http://www.objc.io/issue-5/view-controller-transitions.html and http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/
I have a UIViewController called DashBoardViewController that acts as delegate for a UITabBar. In its xib I have placed a UITabBar with 3 UITabBarItem.
Each of these items activate a different View Controller, let's call them ViewController1, ViewController2, ViewController3
DashBoardViewController is supposed to show ViewController1 and select the first bar on loading, so in my initWithNibName I have what follows:
...
ViewController1* vc = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
[self.view addSubview:vc.view];
self.currentViewController = vc;
...
I implement the UITabBarDelegate having something as follows:
if (item == viewController1Item) {
ViewController2 *vc2 = [self.childrenControllers objectAtIndex:1];
[self.currentViewController.view removeFromSuperview];
[self.view addSubview:vc2.view];
self.currentViewController = vc2;
} ...
Problem
The View Controller in the first UITabBarItem always works as expected, extending it to the full size of thew view.
However, in the second and following tabs, this doesn't happen: the view doesn't extends. This shows if, for example, I align a tab with the bottom in the ViewController2 XIB: this will not be at the bottom when viewed inside the UITabBarItem.
Note
Please note that this is not related to the XIB: if I invert ViewController1 and ViewController2, it will be ViewController1 the one failing to extend. It's related to the UITabBarItem.
Ideas
Possibly, this depends by the way I addSubview when I call the DashBoardViewController's initWithNibName. But I can't find a way to explain this.
Other details
All the XIB are set with "Size = none".
I can't really speak to the way you have your XIB setup without seeing it, but I can make a couple of suggestions.
The behaviour that you're trying to implement by removing & adding subviews to DashBoardViewController should really be handled by a UITabBarController. This provides a UITabBar, a view for your content and handles the logic of switching between UIViewControllers while keeping layout sane and being part of the SDK.
If for some reason you can't, or don't want to use a UITabBarController, I'd suggest implementing a viewWillLayoutSubviews method on your DashBoardViewController, like so:
- (void)viewWillLayoutSubviews
{
if( self.currentViewController )
{
self.currentViewController.view.frame = self.view.bounds;
}
}
Maybe also try adding the self.currentViewController.view.frame = self.view.bounds; line after you've swapped ViewControllers too, for good measure. This will make sure that the frame of your current ViewController's view is always sized to fill the bounds of DashBoardViewController's view.
This isn't the 'Proper' way to do it though, I'd really recommend using a UITabBarController if you can, since you don't know how much else of UITabBarController you'll end up re-implementing if you start rolling your own controller.
Any further problems will most probably be to do with the internal layout of your sub-ViewControllers, rather than their size / position in DashBoardViewController's view.
On your XIB File make sure that your set the flexible height to stick to top and bottom, this way the UITableView will always have the same height as the 4" display
I have a UISplitViewController in an iPad app. When something is selected from the table I want to fade in a modal view controller over the detail view. I can present it without a problem, but for some reason I can't get it to match the frame of the detail view. I would like it to stick to the detail view controller frame on rotation as well. Does anyone have any experience with this? This is my code to display. The detail view controller reference is set in the app delegate and passed down the table controllers.
QuestionViewController_iPad *questionView = [[[QuestionViewController_iPad alloc] initWithNibName:#"QuestionViewController_iPad" bundle:nil] autorelease];
questionView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
// Not quite
questionView.modalPresentationStyle = UIModalPresentationCurrentContext;
questionView.questionQuizCon = [QuestionQuizConnection firstQuestionForQuiz:quizCatCon.quiz];
// Maybe something like this?
[self.detailViewController presentModalViewController:questionView animated:YES];
When the modal view presents, it matches the size of the detail view controller, but it doesn't but it sits on the top left of the screen behind the master view controller. It also doesn't resize on rotation. I have the springs and struts set to auto size and fill. The height changes on rotation but it won't fill the width.
I couldn't get this to look right any way I tried it so I ended up just using view transitions to make it look like pages being torn off a notebook. That looks better anyway.
// Transition the view on as a subview.
[UIView transitionWithView:self.detailViewController.pageView duration:1.0
options:UIViewAnimationOptionTransitionCurlUp
animations:^ {
questionView.view.frame = CGRectMake(0, 0, self.detailViewController.pageView.frame.size.width, self.detailViewController.pageView.frame.size.height);
[self.detailViewController.pageView addSubview:questionView.view];
// Watch this one
self.detailViewController.currentQuestionViewController = questionView;
}
completion:nil];
After [self.detailViewController presentModalViewController:questionView animated:YES]; you should set center property and/or frame of questionView. Be sure that you set it after presenting modal view.
I am writing an iPad app that requires the user to enter names and addresses and would like to use ABNewPersonViewController as the interface. The documentation says that this view controller should only be used from within a navigation controller. Is there anyway I can use just the ABNewPersonViewController in a subview (with a navigation controller) without it taking over my whole screen? I assume I can do this easily enough in a popover but I would prefer to have it integrated into my interface... Thanks for any help you can provide!
Consider presenting your UINavigationViewController by presentModalViewController:animated: and change modalViewPresentationStyle to UIModalPresentationPageSheet.
See the reference : http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Well, after much looking into this, it does not see that there is any way to use the address book UIs in a subview but they do work quite well in a popover view. However, this popover needs to be exactly 320x460 pixels or some other number with the same aspect ratio for the "add photo" to work correctly (otherwise the photo is stretched). In the popover's view controller viewDidLoad method I added:
self.picker = [[[ABNewPersonViewController alloc] init] autorelease];
self.picker.newPersonViewDelegate = self;
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:self.picker] autorelease];
self.navigationController.view.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:self.navigationController.view];
This seems to work fine. Let me know if you know of something better.