Unable to show tableview from button press on UIView xib - ios

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()
})
}

Related

How to display a hidden part right underneath the submit button after it's clicked?

So, I'm trying to make a hidden part visible after clicking the submit button. More specifically, this part should be a TableView that will display user selections/entries before they hit the submit button. Is there a way to do that?
Please see the images as examples.
I have tried to use ExpandableTableViewController 2.0 in CocoaPods. It uses a Tableview Controller to make table cells expandable. However, I couldn't figure out how to implement/connect it into my ViewController. If you have a better way to do it, please let me know!
Thank you in advance for your help!
You can also manage the height constraint of UITableView's in your code to get the expand/collapse effect
Here is the sample code
#interface ViewController ()
{
BOOL toggleToshow;
}
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraintTbl;
- (IBAction)btnSubmitClicked;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
toggleToshow = YES;
self.heightConstraintTbl.constant = 0;
}
- (IBAction)btnSubmitClicked {
[UIView animateWithDuration:1 animations:^{
self.heightConstraintTbl.constant = toggleToshow?285:0;
toggleToshow = !toggleToshow;
[self.view layoutIfNeeded]; // Make sure to Call this for getting nimation effect
}];
}
Here is the swift version
import UIKit
class AnimateViewController: UIViewController {
var toggleToshow = true;
#IBOutlet weak var heightConstraintTbl: NSLayoutConstraint!
#IBAction func btnSubmitClicked() {
UIView.animateWithDuration(1, animations: { () -> Void in
if self.toggleToshow{
self.heightConstraintTbl.constant = 285
}else{
self.heightConstraintTbl.constant = 0
}
self.toggleToshow = !self.toggleToshow
self.view.layoutIfNeeded(); // Make sure to Call this for getting nimation effect
})
}
override func viewDidLoad() {
super.viewDidLoad()
toggleToshow = true;
self.heightConstraintTbl.constant = 0;
// Do any additional setup after loading the view.
}
Happy coding...
See the screen shot to link the constraint
In your viewDidLoad(), hide the table, and move your "Back" & "Next" view up, using self.Backview.center.y += 350 (or however many pixels needed to make it close).
Then once you receive an entry, unhide it, and slide the backView down, using
UIView.animateWithDuration(0.5, delay: 0.0,
options: [.CurveEaseOut], animations: {
self.backView.center.y -= 350
}, completion: nil)
This animation provides a nice sliding view, and eases in, giving the illusion of a slide. This is an effect I have implemented before and really works well.
Good Luck!

UIView animation animates but immediately moves back to original position

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];
}];
}

Setting frame value for all items in IBOutletCollection

I created an IBOutletCollection with some UIElements (Label, Button, TextField) that i would like to move on a special event.
thats what I have so far:
#IBAction func moveDown(sender: UIButton) {
UIView.animateWithDuration(0.4, animations: {
for subview in self.moveOutViews {
var offset = CGFloat(700);
var newY = subview.frame.origin.y + offset;
subview.frame = CGRectMake(subview.frame.origin.x, newY, subview.frame.size.width, subview.frame.size.height);
}
}, completion: {
(value: Bool) in
UIView.commitAnimations();
});
}
now my problem is, when the Animation is completed, and i want to interact with the UIElements (TextField) on the new position, all views 'jump' back to the origin position.
maby it's a problem that the 'sender' is part of the IBOutletCollection?
It's an iPad for iOS 8.3 app and i am using Swift.
Edit: I made a workaround with an UIScrollView. But I would like to know why the first idea isn't working.
Since we don't know how your view is setup I will have to guess that it is one of two things:
Like #Paulw11 suggested in his comment. You are editing the frames of views that are held by constraints. When the view is laid out again all views snap back to positions determined by the constraints. Event though you say that you are not using constraints it is possible that translatesAutoresizingMaskIntoConstraints is enabled for your views or that your xib/storyboard is set to use constraints and so constraints are automatically generated for you. One way to check this is to just log the constraints property of a subview.
You have code somewhere else in your app that is changing the position of your views and it is inadvertently being called.

iOS 8 AutoLayout changing the position of a view

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.

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