cocoa: how to implement a table animation? - macos

I'm curious how to implement the following app animation:
after I click Alcides, the app will gradually show a new view on the right and the left table width will be 1/2 of the original.
if I want to implement it, how can I do?what data structure and animation should I use?

The answer with most custom animations is to think about what you want to do and do it. Trite but true.
Cut the width of the tableview in half at animation speed X
Move the RH detail table in from right at animation speed X
You will need to have your ViewController for the scene as a container for the pair of tables. But the tableviews may have their own view controllers which the container manger should keep a strong reference to.
ManagerViewController -> UIView -> PeopleTableView -> PeopleTableViewController
-> DetailTableView -> DetailTableViewController
So in code...
detailTableView.frame = Frame_with_x_aligned_to_RH_edge_of_screen;
[UIView animateWithDuration:X
animations:^{
peopleTableView.frame = Frame_with_half_its_fully_expanded_width;
detailTableView.frame = Frame_with_x_aligned_to_edge_of_peopleTable;
}
completion:^{ //stuff to do at the end of the animation
}];

Related

Override the Autolayout center values of UIButton in a Subview # viewDidLayoutSubviews

I use Autolayout for a fairly complex Menu and really need it. All Buttons, UIViews etc. of my Menu are in a separate UIView called "menuSubview".
If the user presses a button the whole "menuSubview" shifts to another position to reveal other parts of the menu. Sometimes the buttons in the menuSubview move as well. I always save the "Menu State" (with Userdefaults in the get-set variable "lastMenu") and have a function to set the alphas and centers according to the saved "Menu State".
I tried calling the "openLastMenu" function in viewDidAppear, viewDidLayoutSubview - all the "viewDid" functions of the ViewController. The "menuSubview" center and alphas of the buttons always behave as expected... but the centers of the buttons simply won't - no matter what "viewDid" I call the function in.
(the code is a lot more complex - I boiled it down to debug and state my point)
override func viewDidAppear(animated: Bool) {
if lastMenu != nil {openLastMenu()}
}
func openLastMenu(){
menuSubview.center.x = view.center.x //works
menuSubview.center.y = view.center.y + 200 //works
button1.center.x = view.center.x - 50 //why you no behave???
button2.center.x = view.center.x + 50 //why you no behave???
button3.alpha = 0 //works
button4.alpha = 0 //works
}
For debugging I even made a button Subclass to fetch the "center" values with a "didSet" if they change. Seems like after taking the correct values they change once more to their Autolayout-Position.
...oh and ignoring the constraints with "translatesAutoresizingMaskIntoConstraints" on the buttons always fucks up the whole menu. I'm starting to get crazy here :)
If you position views using autolayout, any changes to the frame, like what you do here with the center property, will be ignored.
What you need to do is identify the constraints that are you need to change to move the views in the desired position. Example:
You want to move button1 50 points to the left of view.center. Assuming view is the superview of menuSubview, you would
1) deactivate the the constraint responsible for button1's horizontal placement. How you do this mainly depends on whether you created the constraints in code or Interface Builder. The latter will require you to create outlets for some of the constraints.
2) create a new constraint between button1's centerX anchor and view's centerX anchor with a constant of -50, like so (iOS 9 code)
button1.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: -50.0).active = true

Animate View Movement for OS X app using Swift

I have two scroll views, one of them with constraints that make it take up the full parent view, and the other right next to it, but hidden outside the bounds of the parent view. I want to animate both sliding left until the second scroll view takes up the full parent view, and the first scroll view is now out of bounds on the left. How do I do this for an OS X app using Swift?
Figured this one out with a little hunting and piecing things together.
Create an IBOutlet for the constraints that you want to change in the animation. In this case, use the leading constraint for each scroll view.
#IBOutlet weak var ScrollView1LeadingConstraint: NSLayoutConstraint!
#IBOutlet weak var ScrollView2LeadingConstraint: NSLayoutConstraint!
Then, use the following:
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = //length of the animation time in seconds
self. ScrollView1LeadingConstraint.animator().constant = //negative width of scroll view
self.ScrollView2LeadingConstraint.animator().constant = 0
}, completionHandler: { () -> Void in
//insert any completion code here
})
This will animate the first scroll view out of frame on the left, and move the second scroll view into its former place.

Xcode - viewDidLayoutSubviews

i have a view inside a viewController, i wanted to start the smaller view outside the viewController in the left, and animate it to the centre when i press a button. so i made it like this:
override func viewDidLayoutSubviews() {
smallView.center = CGPointMake(smallView.center.x - 400, smallView.center.y)
}
And it works perfectly!, the problem is i have a text view inside that smaller view, and every time i start editing it it jumps outside of the main viewController right where it was, and i have to press the button again to bring it inside.
How to fix this?
PS: i tried positioning it to the centre when i start editing the text view like this:
func textViewDidBeginEditing(textView: UITextView) {
smallView.center = CGPointMake(smallView.center.x + 400, smallView.center.y)
}
But it doesn't work. and the method is connected to the textView properly(delegate)
PS2: i also have imagePickerController inside my viewController.
OK, as you're using Auto Layout.
The first rule of Auto Layout (you will see this in any Auto Layout book) is that you absolutely cannot touch the frame or center of a view directly.
// don't do these
myView.frame = CGRectMake(0, 0, 100, 100);
// ever
myView.center = CGPointMake(50, 50);
You can get the frame and center but you can never set the frame or center.
In order to move stuff around using Auto Layout you need to update the constraints.
For instance if I set up a view called myView and want it to grow and shrink in height I would do something like...
Set the top constraint to the superview at 0.
Set the left constraint to the superview at 0.
Set the right constraint to the superview at 0.
Set the height constraint to 50 (for example) and save it in a property called heightConstraint.
Now to animate the change in height I do this...
self.heightConstraint.constant = 100;
[UIView animateWithDuration:1.0
animations:^ {
[self.view layoutIfNeeded];
}];
This will then animate the height from 50 (where it was when I set it) to 100.
This is the same for ANY animation of views using Auto Layout. If (for instance) I had saved the left constraint I could change that and it would increase and decrease the gap from the left edge of the superview to myView.
There are several really good tutorials about AutoLayout on the Ray Wenderlich site. I'd suggest you take a look at them.
Whatever you do, I'd strongly suggest not just disabling Auto Layout. If you don't know how to use Auto Layout then you will very quickly fall behind with iOS 8 and the new device sizes.

iOS animation: Drop down that keeps it position

I´m trying to create a drop down menu that will display a set of controls. I got the animation working but the whole "button" moves with the animation.
My button is a UIView which is named settingsPanel, this is my code so far:
[UIView animateWithDuration:1.0f animations:^{
self.settingsPanel.bounds = CGRectMake(self.settingsPanel.bounds.origin.x, self.settingsPanel.bounds.origin.y, self.settingsPanel.bounds.size.width, self.settingsPanel.bounds.size.height + 300);
}];
I just want the height of the panel to change, and it does, but the whole view moves up a bit as well.
How can I create a animation that justs increases the height downwards?
You need to set the frame, not the bounds.
[UIView animateWithDuration:1.0f animations:^{
self.settingsPanel.frame =
CGRectMake(self.settingsPanel.frame.origin.x,
self.settingsPanel.frame.origin.y,
self.settingsPanel.frame.size.width,
self.settingsPanel.frame.size.height + 300);
}];
Frame is an external coordinate. When you change the frame, you change the actual position of the view within its superview, so you can keep the origin and width the same and just increase the height.
Bounds is an internal coordinate. When you change the bounds, the system has to decide what to do about the frame; its solution is that the change happens around a stationary center position. So the top moves upward as the height grows downward.

Rotate UIView to give perspective

I want to change the perspective of a UIView that is in my Viewcontroller. I think that I have to transform this UIView layer, but I don't know how.
I've tried the following code but it is not working
UIView *myView = [[self subviews] objectAtIndex:0];
CALayer *layer = myView.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
I've also tried with the following code:
-(void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGAffineTransform transform = CGAffineTransformIdentity;
transform.b = -0.1;
transform.a = 0.9;
CGContextConcatCTM(ctx,transform);
// do drawing on the context
}
and this too:
CALayer *layerA = [[self.view.layer sublayers] objectAtIndex:0];
layerA.transform = CATransform3DConcat(layerA.transform, CATransform3DMakeRotation(DEGREES_TO_RADIANS(45),1.0,0.0,0.0)
Neither of them worked. How can I change the perspective of a UIView?
In other words, I will put an example. Image this sample code, a rotation Pie RotationPie sample. I would like to change the perpective of it, in the x or z asis.
Your first solution works on my end. It appears like this:
Can You show your whole class code, if it doesn't work the same on your end?
EDIT
Ok, I've reconfigured provided code example, to show how it is possible:
(download here updated code example :http://www.speedyshare.com/dz469/download/Wheel-demo.zip)
And it looks like this:
I am only applying transformation to base subview. All views that are as subviews to that view, will be transformed as well. If You want corresponding subview to have different transformation - it will be harder, because, then You must take in consideration parent view transformation, to calculate new one - it can get really difficult.
But I've done some simple - multi-view level transformations. For example - to achieve effect, that view scales, moves, and rotates:
I've applied movement transformation to parentView
I've applied rotation transformation to parentViews first subview;
I've applied scale transformation to parentViews first subviews subview.
EDIT
Ok, I've reconfigured provided code example, to show how it is possible, in order to leave wheel in transformed position:
(download here updated code example :
http://www.speedyshare.com/5d8Xq/download/Wheel-demo2.zip )
Problem was - in this case, I was adding transformation to wheel itself - and it appears, that Wheel is based on transformations also. Therefore- when You touched it - it replaced existing transformations and applied it's own (to rotate arrows when user swipes wheel).
So - to leave it in perspective while we interact with it - we need another view layer.
I created a new View (lets call it parent view), and added wheel as a subview to this view.
Then I apply transformation to parent View instead of wheel. And it works !
I Hope it helps and You understand now more about transformations :)

Resources