How can I make a custom view in iOS which appears above the existing view,but smaller? It should be like UIAlertView, but taken from a .xib file. After user taps a certain button, the small view vanishes and the normal view appears.
If this is posiible, how can I do it? And.. if it's not hard for you, please, include code.
Thanks in advance!
I think what you're looking for is a modal view. Modal views make it easy to have a view take over the screen for a little while, then when they get dismissed have the background view resume where it left off without having to worry about who's on top or handling events in partially-obscured views.
Here is Apple's article describing it.
They key is to have the controller class for your view call [self presentModalViewController:popupController animated:YES]; where "popupController" is the view controller for the view you want to show up. When you're ready to make it go away, call [self dismissModalViewControllerAnimated: YES];
You can just use the addSubview: method on your UIWindow or your visible UIViewController's view to show the UIView, and you can hide/remove it later by calling removeFromSuperview on the presented UIView.
Related
I am trying to make some kind of popup view when a button i pressed on the iPhone. And it would be nice if I could manage that popup view with a ViewController. I have found out that the UIPopoverController could have been the solution, but it seems that it only works on the iPad...
But anyway, are there any similar solutions for the iPhone?
I am using storyboard
Check out these repos on Github:
https://github.com/werner77/WEPopover
https://github.com/50pixels/FPPopover
Create a separate view controller and resize its xib file and make it look like a popup.
Then ADD this view controller as a subview, and also add it as childController too.
[self addChildViewController:self.popOverViewController];
[self.view addSubview:self.popOverViewController.view];
Now Make it hidden initially.
self.popOverViewController.view.hidden = YES;
If a user taps on Button then using fade in & Fade out animation you can hide/unhide it.
I can tell you how to fade in and fade out if you want to know it further, I hope you can do it easily.
In interface builder make a UIView size of the screen and then make another in that Uiview with the style, size and the such for your pop over. Make its class, hook everything together.
CustomPopUpView *view = [[CustomPopUpView alloc] initWithFrame.....]
Add this all to your UIViewController with
[self.view addsubview:view]
Then attach a tapGestureRecognizer to the back view that animates the whole view off screen when tapped. So now if they click off your pop over view it close it will animates it off screen.
Hope this makes sense.
BooRanger
Is it possible to view the viewcontroller behind the displayed one? I have a viewcontroller with a scrollview, which has imageviews added as subviews and would like the view that presented this viewcontroller to be visible behind the presented view controller.
I have set all the views, the viewcontroller view too to have a clear color background, but still there is a black background. when I dismiss the viewcontroller, I see 2 layers being dismissed. one has alpha dropped, the other not.
Is there an easy way to make this effect possible?
Its not possible. When a new view controller is pushed or presented as modal view, the previous view controller will be removed from the display(may be UINavigationController/iOS hides it). The rule is only one view controller would be visible at a time. So you will see the color of your window(the black color you've mentioned) in the background.
What you could do is make a screenshot before displaying the other controller. and send this image to new controller to be displayed as background.
This will only work for static content, but you could do something like the curl display.
You can do this but the truth is what EmptyStack says.
You can use setFrame of the subView and add it on the viewController. Also use below method to set the index of the added View. By default currentView has Index 0.
[self.view insertSubview:myView atIndex:0];
or you can try below methods as per your logic
insertSubview:aboveSubview:
insertSubview:atIndex:
insertSubview:belowSubview:
addSubViews:
bringSubviewToFront:
removeFromSuperview:
So I have two search bars, a couple of buttons and a tableView below those (yes, all these) in one view. And I also have a navigation bar on top of it all with a back button.
For a particular operation, I remove all search bars, buttons and I display only one uitableviewcell in my view.
If I press edit, I want the whole view to be reloaded, not just the tableView but I want the view to have the search bars and buttons and the navigation screen.
I did [self.view reloadInputViews] in the IBAction of the edit button. Control goes here, but the view is just not reloaded. Why?
reloadInputViews is specifically used for views that are firstResponders. Probably self.view is not the first responder at that time. But why you want to do all this using "reloadInputViews", it wouldn't be easier to use: [self.view setNeedsLayout] ?
A better way to handle refreshing the state of a view is to abstract the configuration of your UIViewController's view's subviews into a custom method that you can call initially from viewDidLoad and again as an action of your UIbarButtonItem.
- (void)viewDidLoad {
//Specific, non repeated view setup
[self resetViewState];
}
- (void)resetViewState {
//Repeatable view setup
}
The reason it's worth making the distinction is because viewDidLoad is called automatically by the system after the view is lazy loaded. By design it's not a method that should be called multiple times per view. It will be called again if the view is discarded and recreated.
You can also move the layout of your UIViewController's subviews into viewWillLayoutSubviews if you need to do layout work, again this gets called by the system at various times.
I do not know how I get the answer myself right after posting it here on StackOverflow. Sorry for the trouble guys (sigh!)
I did [self viewDidLoad];
I've been working pretty extensively the last couple months with UIImagePickerController, particularly with the new capabilities in OS3.1 and newer to overlay views on-top of the camera view. This has worked just fine.
However, I am currently working on a project where I'd like to be able to display the camera view of the UIImagePickerController within an existing view. Essentially, the exact opposite of what I've currently been doing.
An example would be a View Controller with navigation components (Think top and bottom horizontal bars with gradients), and upon tapping a button on one of these bars, then content area displays the camera view. The shutter animation would should up, and the top and bottom navigation bars would remain always on-top.
I've had success adding the UIImagePickerController to the window view, as well as presenting it modally, but haven't had any luck adding it as a subView.
ex:
[window addSubview:camera.view];
[self presentModalViewController:camera animated:YES];
All you need to do is call viewWillAppear and viewDidAppear.
Here is an example where _pickerController is an instance of UIImagePickerController:
[self.view addSubview:_pickerController.view];
[_pickerController viewWillAppear:YES];
[_pickerController viewDidAppear:YES];
Call viewWillAppear:YES on the image picker controller after adding its view to your view. Skip the modal view controller business.
I don't think the API provides direct access to the actual view of the UIImagePickerController. The class is actually a subclass of UINavigationController so I don't think it has an actual view itself but rather manages the calling of its subcontrollers and their views.
When you call the UIImagePickerController modally, its doesn't add the views it controls as subviews to the window (or any other view). That is what a modal view means. It presents the view off to the "side" of the view hierarchy.
Even if you could hack this together, I think Apple would reject it as not being part of the API and for violating the HIG.
I'm looking for a way to slide the keyboard into view from the right, like what happens in the Contacts application when you edit a note.
My problem is that when I call [someTextView becomeFirstResponder] in viewWillAppear, the keyboard immediatly pops up with no animation. And when I call it in viewDidAppear, the view first slides in from the right (UINavigationController does the sliding), and then the keyboard slides in from the bottom.
Is it possible to have the keyboard slide in from the right, together with the view?
Solution
In iOS 7, calling becomeFirstResponder on _textView in viewDidLayoutSubviews works.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[_textView becomeFirstResponder];
}
Note: Doing it in viewWillLayoutSubviews also works.
Explanation
Read the discussion in the docs for becomeFirstResponder.
You may call this method to make a responder object such as a view the first responder. However, you should only call it on that view if it is part of a view hierarchy. If the view’s window property holds a UIWindow object, it has been installed in a view hierarchy; if it returns nil, the view is detached from any hierarchy.
When using a navigation controller to push your custom view controller onscreen, self.view.window is still nil by the time either viewDidLoad or viewWillAppear: is called. So, _textView.window is also nil in the same methods, since _textView is a subview of self.view, i.e., they're both in the same window. No matter how you present your custom view controller, self.view.window (and thus _textView.window) is also nil in initWithNibName:bundle:. self.view.window is set by the time viewDidAppear: is called, but that's too late because by that time, the navigation controller has already completed the animation of pushing the view onscreen.
self.view.window is also set by the time either viewWillLayoutSubviews or viewDidLayoutSubviews is called and these methods are called before the push animation of the navigation controller begins. So, that's why it works when you do it in either of those methods.
Unfortunately, viewWillLayoutSubviews and viewDidLayoutSubviews get called a lot more than just on the initial navigation controller push. But, navigationController:willShowViewController: and willMoveToParentViewController: get called too soon (after viewDidLoad but before self.view.window is set) and navigationController:didShowViewController: and didMoveToParentViewController: get called too late (after the push animation).
The only other way I can think of doing it is to somehow observe the window property of _textView so that you get notified when it changes, but I'm not sure how to do that since window is readonly.
All you need to do is tell the text view in question to become the first responder in the viewDidLoad method of the view controller you're pushing onto the navigation stack:
override func viewDidLoad() {
super.viewDidLoad()
someTextView.becomeFirstResponder()
}
This works in iOS 8. The keyboard slides in from the right along with the view.
In iOS 7 (or any version before) you can make a simple thing in loadView, viewDidLoad or viewWillAppear
[yourTextView performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
In this case you will get left-to-right appearance of the keyboard aligned with the motion of pushing view controller.
For iOS 7 I've found the following solution to work the best for me:
-Import UIResponder-KeyboardCache to your project.
-Add [UIResponder cacheKeyboard:YES]; to the viewDidLoad of the view before the keyboard view. It might be better to do this immediately when the application loads or during a time convenient when you can afford it (during an HTTP request, for example). In most cases, simply in the view before is sufficient.
-Add the following to the viewDidLoad of the keyboard view.
dispatch_async(dispatch_get_main_queue(), ^{
[_textField becomeFirstResponder];
});
To explain, this will preload the keyboard view, which will remove the delay from the first call of the keyboard view. Calling becomeFirstResponder on the text field in the main queue causes it to slide in with the view instead of animating upward before the view slides in.
You could try sending the becomeFirstResponder message to the new view controller before you push it onto the stack. For example:
-(void)functionWhereYouPushTheNewViewController {
yourNewViewController *newVC = [[yourNewViewController alloc] init];
[newVC.yourTextView becomeFirstResponder];
[self.navigationController pushViewController:newVC animated:YES];
}
I have found that changing animations on things like they keyboard is pretty tough though, and if you read the Human Interface Guidelines Apple makes it pretty clear that they want certain things to act in certain ways, all the time. There are ways to change the behaviors of certain animations but they often involve undocumented API calls and are grounds for rejection from the app store. It would be a violation of HIG to have pushed views slide up from the bottom, for example.
Hope this helps.