This is written in Swift 2 in Xcode 7.
I have a UIView, which originally is set to be below the screen. Upon being triggered, it should slide up from the bottom of screen. This is the code for the animation:
func durationView(sender: UIButton){
let heightOffset = self.durationNotificationContainerView.frame.height
self.durationNotificationContainerView.translatesAutoresizingMaskIntoConstraints = false
UIView.animateWithDuration(0.2, animations: {self.durationNotificationContainerView.frame = CGRectMake(self.durationNotificationContainerView.frame.origin.x, self.durationNotificationContainerView.frame.origin.y + heightOffset, self.durationNotificationContainerView.frame.width, self.durationNotificationContainerView.frame.height)})
}
What happens right now is when I press the UIButton that triggers this view, it slides up and then immediately back down (to outside of the screen). I should also point out that in my storyboard I have some views added manually with AutoLayout constraints, so I don't know if that's what is messing up my animation.
In Autolayout, constraints need to be changed and updated in the the animation as seen below:
- (IBAction)moveAction:(id)sender {
self.spaceConstraint.constant += 220;
[UIView animateWithDuration:0.5 animations:^{
[self.imageView layoutIfNeeded];
}];
}
Related
In my app users profiles are contained on a xib file that is shown when the user taps a button on the Main View Controller. At the base of the xib pop-up is a button that shows user's the leaderboard tableview of scores of other users in their area. The issue I am facing is that on iPhone 8 the tableview is able to slide up and be shown however on iPhone X & iPhone 11 nothing happens. Below I will include a screenshot of the view hierarchy and constraints
The code inside the IBAction is executed as such
#IBAction func userTappedScoresIcon(_ sender: Any) {
//load tableview data
score_tblView.reloadData()
scoreViewTopConstraint.constant = 0.0
UIView.animate(withDuration: 0.25) {
self.scoresView.frame = self.profile_scroller.bounds
}
}
I have tried changing the constraints in storyboard as well as removing the constraint at the top of the tableview but nothing has been successful. any help would be much appreciated!
You can try with this example
self.topConstraint.constant = -100.0;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
func AnimateBackgroundHeight() {
UIView.animateWithDuration(0.5, animations: {
self.heightCon.constant = 600 // heightCon is the IBOutlet to the constraint
self.view.layoutIfNeeded()
})
}
I'm working on an app that I had originally made for iOS 7 which worked perfectly fine, but now after moving to iOS 8, things aren't working properly anymore. Basically, I have a view with a button. When I tap that button, another UIView with a UITextField "slides" up onto the screen from a position below the visible screen area. The problem comes when I tap the UITextField to type into it, where a keyboard comes up, but the view with the UITextField goes back to its initial position off the screen. This was not happening in iOS 7, so I'm assuming this has something to do with the changes to autolayout for iOS 8. Does anyone know what I can possibly do to fix this? I would rather not turn off autolayout if I don't have to, as a good portion of my app depends on it.
Here is some code to show you what I'm referring to. In my example, "locationField" is the button that gets tapped, and "locationView" is the UIView that slides onto the screen:
- (IBAction) locationFieldTapped:(UIButton *)sender {
[self slideViewUp:_locationView];
}
- (void) slideViewUp:(UIView *)slidingView {
if (viewIsSlidUp) {
return;
}
CGRect frame = slidingView.frame;
int availableHeight = self.view.frame.size.height;
// don't move view up if it's already moved up or in the process of moving up
if (frame.origin.y < availableHeight) {
return;
}
viewIsSlidUp = YES;
// move view just off screen for animation start, in case it's not already there
frame.origin.y = availableHeight;
slidingView.frame = frame;
[UIView animateWithDuration:0.5f animations:^{
CGRect newFrame = frame;
newFrame.origin.y = availableHeight - CGRectGetHeight(frame);
slidingView.frame = newFrame;
}];
}
You need to set the constraints of the view you're animating in iOS 8 and the autolayout system then deals with the rest. You can create an IBOutlet to an NSLayoutConstraint and simply change its constant property. Then you call the layoutIfNeeded method on the edited view's super view in the animation block.
I am trying to make a UITableView appear when a user taps on a button and disappear when the button is re-tapped.
I implemented the following code but nothing seems to appear when I tap the button.
- (IBAction)dropDown:(UIButton *)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.6];
CGAffineTransform transfrom = CGAffineTransformMakeTranslation(0, 200);
self.markersTableView.transform = transfrom;
self.markersTableView.alpha = self.markersTableView.alpha * (-1) + 1;
[UIView commitAnimations];
}
What may potentially be the issue?
EDIT:
I was able to make the UITableView appear and disappear by adding self.markersTableView.hidden = YES; in viewDidLoad() and self.markersTableView.hidden = NO; in the IBAction method.
However, the table view disappears when I initially tap on the button as shown in the screenshot:
The fading of the rows is an indication it is moving down the screen, and then it disappears.
It only reappears when I re-tap on the UIButton the 2nd time.
Any clues?
Don't use a transform on your table view. That will make it LOOK like it's in a different position, but it won't respond to taps correctly.
Instead, use the newer UIView block-based animation methods and change the view's center.
The code might look like this (if you're NOT using auto-layout)
[UIView AnimateWithDuration: .2
animations: ^
{
CGPoint center = self.markersTableView.center;
center.y += 200;
self.markersTableView.center = center;
}
];
If you're using auto-layout, though, that won't work and you will need to animate the view's position using constraints.
From memory, here's an outline of how to do auto-layout based animations: You would create a vertical position constraint on your table view and connect the constraint to an IBOutlet in your view controller. In your animation code you change the constant of the constraint (the vertical position) and then in the animation block, send the view a needsLayout message.
I have a problem with a uiview that placed in story board in one position and after the app start I move the uiview to second position with animate With Duration with a button from code.
int alpha = -212;
if(!flag)
{
alpha = 212;
}
[UIView animateWithDuration:0.8 animations:^(void)
{
keyboardView.frame = CGRectMake(keyboardView.frame.origin.x, keyboardView.frame.origin.y + alpha, keyboardView.frame.size.width, keyboardView.frame.size.height);
}
completion:nil];
After I do something like reload label or change something in text filed the
uiview back to story board position.
labelTest1.text = tempTextFiled;
[textField setText:tempTextFiled];
How can I keep the uiview stay in the second position ?
Try to create this view without the storyboard (code only). this will fix your issue.
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.