Animate UITextField - ios

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.

Related

why Button SubView will not go to the back in swift 4?

I have a view class with xib file so I want to use this view at the background of the button so I used subview but the problem is that the subview of the button will be inFront of the button so I can't click button any more I used UI Debugging mode and I realized that the button is at the back of the view so I used send to back in my codes But still the view is inFront of the Button !
let adsView = videoAdsView()
func adsOutlet() {
self.adsView.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
self.showAdsOutlet.addSubview(adsView)
self.showAdsOutlet.sendSubview(toBack: self.adsView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
adsOutlet()
}
put following code at the end of adsOutlet method:
self.adsView.isUserInteractionEnabled = false
If you want to add your button as a subview of your background view then you can just do that, and your button will be in front of the background:
self.backgroundView.addSubview(adsButton)
If you don't want adsButton as a subview of the backgroundView but you want to make sure it's presented in front of the backgroundView then assuming that both are subview's of the parent view do this:
self.view.sendSubview(toFront:adsButton)
Please try this code:
Make the button background color clear.
Then write this code:
self.view.bringSubview(toFront: showAdsOutlet)
It may helps to you. Thank you

How to add a button to a Tab Bar Controller

I mean, not a UITabBarItem, an UIButton. For example, in the Deezer app, the middle button shows a view with an animation that covers the entire screen. I don't want the button to be rounded. Just to execute the action.
This is a very simplistic example. You'll still have to modify it to fit your needs, but if you have a UIBarButtonItem called button that you've added to your navigationBar, you should be able to do something like this, in viewDidLoad
button.action = #selector(showView)
Then you just need to create a function to be called.
func showView() {
let myView = UIView()
self.view.addSubview(myView)
}
Of course this has no animations, but again this is just to point you in the right direction.

How do I make a label slide onto the screen when a button is pressed? SWIFT 2

I'm building an iOS app that takes some text from a website and displays it in a label when a button is pressed.
I'd like the label to move onto the screen from below when the button is pressed, how is this done in Swift 2?
I've started off using this code to move the label off the screen when the view appears, but I can't find a way to animate it back onto the screen
override func viewDidLayoutSubviews() {
label.center = CGPointMake(label.center.x, label.center.y - 400)
}
Very simple approach. Set the CGPoints to where you want to label positioned.
UIView.animateWithDuration(1, animations: {
label.center = CGPointMake(label.center.x, label.center.y+400)
})

presenting a modal view controller while the keyboard is active

So I basically have a form, consisting of several text fields. The user types into the fields as usual. But the user also has the option of double-tapping a text field, which presents a modal view controller, allowing the user to choose from a number of options relating to that field.
Can I somehow present the modal "over" the keyboard, such that when it is dismissed, the keyboard is still active for the field that had been first responder before I presented the modal?
Right now, the keyboard dismisses while the modal appears, and reappears as the modal is dismissed. It looks clunky to me, and distracting. Would love to streamline it, and reduce the amount of animation onscreen.
Edit: I've updated this answer for iOS 12 and Swift. The revised example project (containing new Swift and updated Objective-C implementations) is here.
You can create a new UIWindow and place that over the default window while hiding the keyboard's window.
I have an example project on Github here, but the basic process is below.
Create a new UIViewController class for your modal view. I called mine OverlayViewController. Set up the corresponding view as you wish. Per your question you need to pass back some options, so I made a delegate protocol OverlayViewController and will make the primary window's root view controller (class ViewController) our delegate.
protocol OverlayViewControllerDelegate: class {
func optionChosen(option: YourOptionsEnum)
}
Add some supporting properties to our original view controller.
class ViewController: UIViewController {
/// The text field that responds to a double-tap.
#IBOutlet private weak var firstField: UITextField!
/// A simple label that shows we received a message back from the overlay.
#IBOutlet private weak var label: UILabel!
/// The window that will appear over our existing one.
private var overlayWindow: UIWindow?
Add a UITapGestureRecognizer to your UITextField.
override func viewDidLoad() {
super.viewDidLoad()
// Set up gesture recognizer
let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapRecognizer.numberOfTapsRequired = 2
doubleTapRecognizer.delegate = self
firstField.addGestureRecognizer(doubleTapRecognizer)
firstField.becomeFirstResponder()
}
UITextField has a built-in gesture recognizer, so we need to allow multiple UIGestureRecognizers to operate simultaneously.
extension ViewController: UIGestureRecognizerDelegate {
// Our gesture recognizer clashes with UITextField's.
// Need to allow both to work simultaneously.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
This is the interesting part. When the gesture recognizer is triggered, create the new UIWindow, assign your OverlayViewController as the root view controller, and show it. Note that we set the window level to UIWindowLevelAlert so it will appear in front. However, the keyboard will still be in front despite the alert window level, so we have to manually hide its window, too.
It is important to not set the new UIWindow as key or to change the first responder from the UITextField or the keyboard will be dismissed.
Previously (before iOS 10?) we could get away with overlayWindow.makeKeyAndVisible(), but now setting it as key will dismiss the keyboard. Also, the keyboard's window now has a non-standard UIWindow.Level value that is in front of every publicly defined value. I've worked around that by finding the keyboard's window in the hierarchy and hiding it instead.
#objc func handleDoubleTap() {
// Prepare the overlay window
guard let overlayFrame = view?.window?.frame else { return }
overlayWindow = UIWindow(frame: overlayFrame)
overlayWindow?.windowLevel = .alert
let overlayVC = OverlayViewController.init(nibName: "OverlayViewController", bundle: nil)
overlayWindow?.rootViewController = overlayVC
overlayVC.delegate = self
// The keyboard's window always appears to be the last in the hierarchy.
let keyboardWindow = UIApplication.shared.windows.last
keyboardWindow?.isHidden = true
}
The overlay window is now the original window. The user can now select whatever options you built into the overlay view. After your user selects an option, your delegate should take whatever action you intend and then dismiss the overlay window and show the keyboard again.
func optionChosen(option: YourOptionsEnum) {
// Your code goes here. Take action based on the option chosen.
// ...
// Dismiss the overlay and show the keyboard
overlayWindow = nil;
UIApplication.shared.windows.last?.isHidden = false
}
The overlay window should disappear, and your original window should appear with the keyboard in the same position as before.
I can't try this right now, but have implemented similar for other purposes. In the action for presenting the modal controller, I assume gesture recognizer or delegate method, first take a screenshot and place it in an imageView over the current subviews. Later when returning, simply remove the imageView.
Might sound crazy but I remember having done this for a transition where the keyboard moving during the transition caused similar clunky behavior. It was not difficult to implement at all.
If you have trouble trying it, perhaps someone will provide some code. I can reference my own work later and add an example, but not now.
#Rob Bajorek's answer is excellent.
For iOS 9,10 there are small changes.
Instead of the code:
[self.overlayWindow setWindowLevel:UIWindowLevelAlert];
[self.overlayWindow makeKeyAndVisible];
Put the following code:
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *lastWindow = (UIWindow *)[windows lastObject];
[self.overlayWindow setWindowLevel:lastWindow.windowLevel + 1];
[self.overlayWindow setHidden:NO];
In order to keyboard to visible any of text accepting fields such UITextField or UITextView or UISearchBar should be the first responder and they should be visible in the view. Meaning responding view should be in the top level hierarchy in the window.
If you don't need this effect, Instead of presenting a ViewController you can add ViewController.view as a subview of your self.view with animation.
You have access to the frame of the keyboard in iOS.
You need to implement code to listen to the keyboard notifications (like UIKeyboardWillShowNotification and UIKeyboardWillChangeFrameNotification). The notification will send you informations about the frame of the keyboard.
Giva a look to the description of the "Keyboard Notification User Info Keys" in the windows reference.
You'll find useful for you purpose:
UIKeyboardBoundsUserInfoKey The key for an NSValue object containing a CGRect that identifies the bounds rectangle of the
keyboard in window coordinates. This value is sufficient for obtaining
the size of the keyboard. If you want to get the origin of the
keyboard on the screen (before or after animation) use the values
obtained from the user info dictionary through the
UIKeyboardCenterBeginUserInfoKey or UIKeyboardCenterEndUserInfoKey
constants.
With the information of the keyboard frame you can show there you modal view.
Just add an tap gesture in your textfield and a UITextfield *flagTextfield;
UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(DoubleTapMethod:)];
doubleTap.numberOfTapsRequired = 2;
[self.txtTest addGestureRecognizer:doubleTap];
-(void)DoubleTapMethod:(UITapGestureRecognizer *)gesture
{
[flagTextfield resignFirstResponder];
NSLog(#"DoubleTap detected");
//Set your logic on double tap of Textfield...
//presents a modal view controller
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
flagTextfield = textfield;
}

How can I flip an iOS UITableViewCell?

I have a tableview with a number of cells. Each cell has a little info "i" button, which I would like the user to be able to click in order to edit the information in that cell, by "flipping" the cell from the right.
I have a separate table cell XIB for each of the two possible cell states, and cellForRowAtIndexPath provides the correct XIB (with a different cell identifier) depending on whether the cell is supposed to be in the regular view or the detail/edit view. This works fine using, e.g., reloadRowsAtIndexPaths to reflect the changed state when the "i" button is pressed.
But I just can't figure out how to animate a flip when the cell's "i" button is pressed. Flipping isn't one of the options for "withRowAnimation" in reloadRowsAtIndexPaths. And using a standard animation approach like UIView animateWithDuration doesn't work: reloadRowsAtIndexPaths just causes the relevant cell to reload instantly, ignoring the animation instructions. I even tried to use drawViewHierarchyInRect to pick up the cell's future state as an image, but I couldn't get the cell to redraw itself quickly enough to be picked up by drawViewHierarchyInRect (and I don't want the user to actually see the result of the animation before the animation).
Does anyone have an idea of how to handle this?
EDIT
To summarize, the challenge I'm having is: is there another way to swap UITableView cell contents with a different UITableViewCell Xib besides reloadRowsAtIndexPaths (which breaks animations), without causing trouble with the IBOutlets of the new Xib? (Loading it as a Nib into a subview seems to break the IBOutlets.) The answers so far haven't addressed this.
It will be complicated if u use two subclassed UITableViewCell, instead use a single subclassed UITableViewCell, and perform flip-animation for example,
let xib contains the subclass UITableViewCell in its contentView add two views
normal View
Flipped View
in this view's add the contents what u want to display, and make sure both hav outlet in the cell
for example that i took
in the above two view first one View-FlipView and its contents label and button and second one is also same as first view, top view should be the normalView
connect the button actions to cell and u just perform like below in custom cell
//flip the view to flipView
- (IBAction)flipButtonAction:(UIButton *)sender
{
[UIView transitionWithView:self.contentView duration:0.6 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
[self.contentView insertSubview:_flipView aboveSubview:_normalView];
} completion:^(BOOL finished) {
}];
}
//flip the view back to normalView
- (IBAction)flipBackButtonAction:(id)sender
{
[UIView transitionWithView:self.contentView duration:0.6 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[self.contentView insertSubview:_normalView aboveSubview:_flipView];
} completion:^(BOOL finished) {
}];
}
and it will look like something below
any problem just comment ... :) hope this helps u .. :)
Swift 4:
#IBAction func flipButtonAction(_ sender: UIButton) {
UIView.transition(with: contentView, duration: 0.6, options: .transitionFlipFromRight, animations: {() -> Void in
self.contentView.insertSubview(flipView, aboveSubview: normalView)
}, completion: {(_ finished: Bool) -> Void in
})
}
//flip the view back to normalView
#IBAction func flipBackButtonAction(_ sender: Any) {
UIView.transition(with: contentView, duration: 0.6, options: .transitionFlipFromLeft, animations: {() -> Void in
self.contentView.insertSubview(normalView, aboveSubview: flipView)
}, completion: {(_ finished: Bool) -> Void in
})
}
You probably don't want to reload the table's data to flip any given cell. Your cells should be able to flip "on their own." So you'll need to subclass UITableViewCell and in your subclass you'll have something like a flip function, that does some animations of the cell's subviews.
Now here's a trick with flip animations. You can't just change the view hierarchy and flip at the same time, or you'll see the "back side" of your view at the wrong time during the animation. Use two animations in a row:
[UIView animateWithDuration:... {
// Flip the content "half way" by rotating 90 degrees about the y axis.
// At the end of this animation your view will be perpendicular to the
// screen and *not visible*.
contentView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);
} completion: {
// Here you can rearrange your views (remember the view isn't visible
// right now!
//
// When the "back side" views are all ready, you can kick off the second
// half of the flip animation.
[UIView animateWithDuration:... {
// Flip *back* to the identity (not all the way around to M_PI)
// because if you flip all the way around your views will actually
// be flipped. You don't want that. Users will instinctively see
// the movement as *continuous* and interpret the flip back and forth
// animation as one continuous rotation all the way around.
contentView.layer.transform = CATransform3DIdentity;
}
}
I can't see why you couldn't use [UIView animateWithDuration...].
You could have two UIViews in each cell who's scale you animate. The first would be visible and the second would be hidden
At the half-way point of the animation, simply hide the first UIView and unhide the second and continue the animation from there.

Resources