Add subView immediately after view presented - ios

I have 2 view A and B.
At view A
presentViewController(viewB, animation: true) {
NSNotificationCenter.defautCenter.postNotificationName("addButton")
}
At view B:
var masterView:UIView!
func addButton(notification: NSNotification){
var button:UIButton!
button.frame = masterView.caculator // set frame for button
self.addSubview(button)
}
When view B finished animation on simulator( go from Bottom). Button added after delay 0.3s.
Following some document, when animation finish, method viewDidAppear called. i tried this way. But as I saw, button added after animation finish 0.3s
How to addButton immediately when animation finish?
Thank you!

I have solved it. Because in viewDidAppear, this method was called when all Layout is loaded.
So we need implement add my button in LayoutSubview Method.

Related

How to set an animation once the view controller is loaded

My goal is to set off an animation when my second viewController is loaded. How do call the function once the view is loaded?
Here is the code:
UIView.animate(withDuration: 1.5, animations: {self.greyScreen.frame.origin.y = -0.39*self.screenHeight}, completion: nil)
Any advice much appreciated!
viewDidAppear() is the method of UIViewContoller Life Cycle which is called once the screen is completely visible i.e. loaded all views into the memory hierarchy. So put your this block of animation into this method. You'll get your animation effect
Place that code inside viewDidAppear.
viewDidAppear is called when the view is shown on the device, so adding that code to this method will trigger the animation as soon as the view is displayed.

First time animating is glitchy

I am animating a view gradientView in/out using the following:
func hideOrShowGradientView(hide: Bool) {
UIView.animate(withDuration: 0.4, animations: {
self.gradientView.isHidden = hide
})
}
This works well, but on the first time, there is no animation. It just appears. On the second and third time it works wonderfully. I've tried calling the animate block on the main thread but no luck there. Why is this animation failing to occur on the first and only first time around? Should I be using another animation method?
Have you tried calling self.view.layoutIfNeeded(). It forces the view and it's subviews to complete any of it's pending animations immediately, which might be interfering with your animation. You can use it like this:
func hideOrShowGradientView(hide: Bool) {
self.view.layoutIfNeeded()
UIView.animate(withDuration: 0.4, animations: {
self.gradientView.isHidden = hide
self.view.layoutIfNeeded()
})
}
Apple recommends calling layoutIfNeeded() twice, once before the animation block which forces a redraw on the view and it's subviews, and it completes any pending animations on the view without waiting for the next update cycle, and call it the second time inside the animation block to make sure that the animation changes will be applied immediately.
I had too much going on the main thread in the init method, which was being called only on the first time the view was being presented. Moved unnecessary initialization into view did appear

How to refresh a View in Swift 3

I use Two view's on same ViewController and use two animation 1. Flip Back Animation 2. Background Horizontal image animation (image view is sliding from right to left on view1).Now, when i flip from view1 to view2 everything is correct But when i flip back from view2 to view1 than (slide image view animation stop to slide and become static on view1). I need to refresh the view1 as it work properly . I used these two suggested method by Ved
View1.setNeedsDisplay()
View1.setNeedsLayout()
But it's also not work . Please share info
Write all the code in viewWillappear() . This will solve your issue.
Must put func in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
func run() { //Here Code Run }
}
You can use a view to refresh by calling
yourView.setNeedsDisplay() //Updates any drawing, including drawRect()
and
yourView.setNeedsLayout() //Triggers layoutSubviews()

Animate UITextField

I need to make it so that when I click a button, the UITextField transforms left onto the view from outside the view. However, when I execute the following code, the UITextField starts off in the middle of the viewcontroller, and then when the button is clicked it transforms left onto the view from outside the view. How can I make it so that when the view loads initially, it is not seen until the button is clicked, using swift.
#IBAction func joinCircleButton(sender: AnyObject) {
let button = sender as UIButton
joinTextField.frame.origin.x=500
joinTextField.frame.origin.y=100
if (button.frame.origin.x - 75>0){
UIView.animateWithDuration(0.5, animations:{
button.frame = CGRectMake(button.frame.origin.x - 125, button.frame.origin.y,button.frame.size.width, button.frame.size.height)
button.transform = CGAffineTransformMakeScale(0.5, 0.5);
self.joinTextField.frame=CGRectMake(self.joinTextField.frame.origin.x - 325, self.joinTextField.frame.origin.y,self.joinTextField.frame.size.width, self.joinTextField.frame.size.height)
})
}
}
You need to put the UITextField, or any object that you wish to hide, outside of the view by using a function called:
func viewDidLayoutSubviews()
This function is called just before the screen is loaded. It gets the sub-views ready but doesn't show them on the screen yet. So this is an opportunity to hide the UITextField from sight like so:
func viewDidLayoutSubviews(){
// Here is just an EXAMPLE of what I'd do with my text field, you can change this however you wish
// The point is that I am putting it away so no one can see it at first, and then later it will show
joinTextField.center = CGPointMake(joinTextField.frame.origin.x-500, joinTextField.frame.origin.y)
}
Now the textfield should be hidden when the view loads and then it can be animated later on.I hope this helped.

UIPageViewController prevent hiding keyboard on scroll

I have a UIPageViewController with multiple UIViewController, each one containing a UITextField.
Whenever I slide the UIPageViewController, the keyboard automatically dismisses. Is there a way to prevent this behavior?
Invoking becomeFirstResponder on the new UITextfield but the animation the won't fix the problem.
You can try to embed the PageViewController as a ChildViewController of an other viewController.
I believe this way the navigation in the PageViewController will not effect the keyboard.
I am not sure if that is needed, but if it is still not working you can set your ParentViewController as the firstResponder when transition occurs.
unfortunately this seems to come from the animation of the transition showing as done, before it is actually done,
the workarounds I can think of are
1. made the animating false
2. set textFieldShouldEndEditing in the next VC to return NO or handle it with a bool
3. add a delay in the animation, or in the next VC viewWillAppear
When using setViewControllers on UIPageViewController (setting a controller without the scroll), it seems that the completion block is called just before the scrollView has reached its final position. When it does, it dismisses the first responder.
The solution we found was to first, grab the scroll view:
// In UIPageViewController subclass
for subview in self.view.subviews {
if let scrollV = subview as? UIScrollView {
scrollV.delegate = self
self.scrollView = scrollV // Optional, we don't really need it
}
}
The scroll view position is done when its offset is the x position of the middle controller. That is, the offset will equal the view's length.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.x == self.view.width {
// Transition is 'really' done.
}
}
At that point, you can send a notification that transition is completed.
What we did, is hold a completion block and call it when the transition is done.
Create a function, so that a controller can pass a block in:
func transitionCompleted(completed:(()->())?) {
self.transitionCompletedBlock = completed
}
When transition is completed:
self.transitionCompletedBlock?()
The controller with the keyboard will look like:
pagerController.transitionCompleted(completed: {
self.textfield.becomeFirstResponder()
})

Resources