I am a total noob developing iOS applications and I'm working in one right now.
I have set up my storyboard with a HomeViewController (main) and inside this, a container view, with another view controller embeded. This child view controller is outside the bounds of the view, and when a click a button in my HomeViewController it gets animated to the top of my app, showing this child with a cool animation. Everything is right.
In my child view controller I only have 3 buttons, and when they are displayed on the screen with this little animation, they are not usable. They don't trigger the action of the button being pressed nor they get "highlighted" with iOS style. Nothing happens.
I have been searching a lot about this, I have tried addChildViewController() on parent, didMove(toParentViewController: UIViewController) on child and I also have added it programmatically. When added programmatically it works OK but the view does not respect the animation, just being displayed in the screen without following the parent's container, which indeed moves with the animation.
What should I do next?
Thank you very much
Edit: My question does not seem to be a duplicate of UIView animations canceling any touch input
I'm using Spring library for the animations. Also, in that thread they are talking about user interaction being blocked while animation isn't finished. That is not my case. Animation is perfectly finished when trying the button interaction.
From my experience, there are two issues which cause this behavior most often:
Some of your container views have userInteractionEnabled set to false, or
Your container view frame is small and you're attempting to tap a button outside the frame of the container which won't work. Consider it like a window to the button and there's an invisible wall blocking touches.
Both of these are best debugged using the Xcode Debug View Hierarchy, or you can also try the Reveal app and see what's going on there.
Finally, this misbehavior was because the wrapping view in my container was smaller than the container, but as these two were out of screen I didn't realise at first. Making the wrapping view big enough to fit the child container was the solution.
Sorry because at last this was a stupid question.
Thank you all
If you use auto layout. You may check out your constraint is correct or not. Especially for biggerOrEqual and smallerOrEqual constraint still need a concrete constraint. eg:
width = 100#750
width <= superView.width#999
You should not forget the first constriant.
Related
(I have read other questions and answers on this topic, but most are very old and do not relate to iOS 9 or 10.)
The app design calls for the top half of the display to always contain the same content. (An image being edited by the user.)
The bottom half of the display needs a UITableView. When a UITableViewCell is tapped, the bottom section needs to transition to a new UIViewController with slide-on animation, similar to how UINavigationController push segues work.
Problem: only the bottom view needs to transition to the new view controller(s), and back again. The upper half of the view hierarchy needs to remain unaffected. For this reason, I can't place everything inside a UINavigationController, and I can't have a UINavigationBar at the top of the screen.
Question: what approach should I take in such a situation, where I need only one UIView hierarchy to transition in push-segue fashion, but not anything else? Thanks.
Edited with Solution
Solution follows, for those following along at home.
Yes, you can actually use a UINavigationController for the bottom half.
If you are using Storyboards, the easiest way to do this is to use a container view for each part of the screen which you then can embed a UIViewController in for the top part and a UINavigationController in for the bottom part. If you are doing this programmatically, just add the view controllers as child view controllers to your app's initial view controller (see this answer for more info) which is essentially what the Storyboard will do for you automatically when using a container view.
As a child view controller, the UINavigationController will act independently from the top UIViewController and should behave as expected.
I recommend the programatic approach for the following reasons:
It helps you understand the inner workings of child/parent view controllers much better which will likely save you a significant amount of debugging time down the line.
It makes adding/removing/swapping child view controllers as simple as a few lines of code. Trying to do this with Storyboards is notoriously hacky and cumbersome.
It's much easier to keep track of changes using GIT (most mid-size/larger companies actually prohibit Storyboards for this very reason)
If you want change in part of the screen you can use container view. For details refer Swift - How to link two view controllers into one container view and switch between them using segmented control?
You can use multiple view in one view controller and can give animation like push or pop to show or hide it.
Second approach is you can use Container View which will give exact effect like navigation stack.
I have a ViewController setup like so:
-View
--scrollView
---contentView (UIView)
All of my content is in the contentView. Most of the content is UITextFields that I added programmatically to fashion a form-like setup. I can touch the text fields when I first enter the View Controller to bring up the keyboard to type on them, however, as soon as I scroll down (so I can see the rest of the textfields on the view) none of them respond to touch, even the ones that I could originally see and interact with when I first entered the view controller. There is, however, one button that I added from the storyboard that will continuously accept touch events even after scrolling, but the textfields I added programmatically will not.
I am not sure what code to place here and I don't have the first clue as to where to look for this sort of situation. Any help would be awesome, this is my first app so things are coming along slowly. Thanks so much in advance.
Code Here
Note: I'm not talking about custom view controller transition effects which can be done by using a custom view controllers it's the iOS 5+ API.
I'm talking about transitioning to another view controller, where a view from the presently displayed view controller is animated to the view controller to be presented's view.
EXAMPLE
-you have friendsViewController which displays a list of the current users friends. Each table view cell has a profile picture and name.
-click on a cell, all other cells fade away and the name and picture animate to the top. At this point, UserProfileViewComtroller is displayed.
THEORIES
-I could easily do this by combining the two view controllers, but UserProfileViewComtroller can be launched from other parts of the app.
-if the UserProfileViewControllers view is instantiated, I could convert the coordinates using UIViews methods
I feel like there is a more appropriate/cleaner solution here which is why I'm asking the community for help :)
It seems to me that what you want is exactly about view controllers transition, since you want to do 'something' that would look to the user as if you took a view from old VC and moved it to the new VC.
Then you're in luck, as you're allowed to move a UIView from one view controller to another using [superview addSubview:view] as part of the transition you want to do.
This can be done on any iOS version, although it's easier now as in iOS 7 there's a delegate you write (see <UIViewControllerAnimatedTransitioning> reference) which has access to both VC's view hierarchies and can change them at will (move one view, fade other views) during transition period.
Also, making your new view controller during the transition transparent (or using old controller's snapshot) will help you hide the fact that VC changed.
Not so much an answer but a technique that might inspire a solution. I did an app that had need for a custom transition like this. The original app arranged itself then took a snapshot, so at the last moment the user is looking at an image. The second viewController was created, given coordinates etc, and the image, then shown immediately. It put the image into its view (subview with same bounds).
At this point the second vc has complete control, and can fade in some other content etc. the reverse was more or less as the start - the image is used, swapped, used removed to uncover the real view content.
Note that this took a bit of time to get it working with no glitches etc.
EDIT: if you are concerned in turning the whole original view into an image, then modify the technique. For instance, in the original view, fade all other content to black but the cell, then snapshot the one cell. The second view will start with an all black background, and place the cell image over top it, then go from there.
EDIT2: As mentioned in the comments, you of course push the second view with no animation, so it happens instantaneously. By setting a small image on the second vc, with an agreed upon background, you can quickly "pass the baton" so to speak and let the second controller go to work quickly and seamlessly.
I have a test app that uses a custom container controller to switch between 2 child view controllers based on the orientation of the device. In the portraitController, I have a button and a slider -- after one rotation to landscape and back to portrait, the slider still works but the button doesn't. After one more back and forth, both UI elements stop responding to touches.
Meanwhile, in the landscapeController, the button works fine for the first 6 times you switch to that controller, but on the 7th, the button only responds on the far left side, and on the 8th, it no longer responds at all.
The views look fine after the rotations -- everything stays in the right place. There's no methods connected to these UI elements I'm just seeing if they are responsive to touch. I have strong references to both child view controllers, so I am presenting the same instance on each rotation. I can post the code for the container controller if it would help.
Does anyone know what's going on here?
I found the answer after much experimenting -- the "Autoresize Subviews" check box in the container controller's view needs to be deselected. I'm not sure what that does exactly, but it was inappropriately resizing the views of the child controllers.
I have a uitableview controller which is a subview to a view managed by a uiviewcontroller. nothing really out of the ordinary but the tableview tracks gestures on the wrong axis(only on device).
Basically you scroll up/down table doesnt do anything, and left/right scrolls table up/down. its super weird. i was hoping somebody has seen this before and maybe know what causes it?
Edit: heres a video
http://c.drunknbass.com/EB7m
at the end i am scrolling a uiscrollview that scrolls normally and is a child of the same uiviewcontroller.view
UIKit relies on there being a key window, and that window having a root view controller, to be able to correctly handle events, and forward them to your code. I suspect that perhaps one of those things is not set up correctly in your app. (Such that the device orientation isn't matching up with the visual orientation of your UI.)
Also note that prior to iOS 5, making one controller's view the child of another controller wasn't really supported by UIKit. It can be done, and mostly works, but you are going to have to manage the forwarding of all of your lifecycle events. (See the notes on controller containment in the docs, and the description of -automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers as well.)