How to rotate an image cumulatively in Swift ? (Xcode 8) - swift

I am trying to make a button in my view that rotates my image of a gimmicky clock by 45 degrees on each tap of the "rotate" button. All tutorials & answers that I researched online only go to the point where you hit the button once, then it resets (in my case, app only does the action once, then does nothing). So I am trying to make it go from 0 to 45 degrees on the 1st tap, 45 to 90 degrees on 2nd tap, and so on, infinitely, ie store the result every time the button is tapped, then continue from there. Any thoughts? Here is my simple code. Any help would be appreciated as am a newbie in coding - many thanks
#IBAction func Rotate(_ sender: AnyObject) {
let rotation: CGFloat = 0.785398
UIView.animate(withDuration: 0.5) {
self.myWatchImage.transform = CGAffineTransform(rotationAngle: rotation)
}
}

Apply rotated:by: to the current transform to get the next one:
#IBAction func doRotate(_ sender: UIButton) {
let rotation = CGFloat.pi / 4.0
let transform = myWatchImage.transform
let rotated = transform.rotated(by: rotation)
UIView.animate(withDuration: 0.5) {
self.myWatchImage.transform = rotated
}
}

Related

Transform collection view cell container after Swipe to right and left

I'm trying to add Swipe to right and left to collection view cell to transform the container to the right and left with a certain angle
Here is my initial setup
private func setupGestures() {
let swipeToRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeRight))
swipeToRight.direction = .right
container.addGestureRecognizer(swipeToRight)
let swipeToLeft = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeLeft))
swipeToLeft.direction = .left
container.addGestureRecognizer(swipeToLeft)
}
#objc func respondToSwipeRight(gesture: UIGestureRecognizer) {
let angle = CGFloat(Double.pi/2)
UIView.animate(withDuration: 0.5) {
self.container.transform = CGAffineTransform(rotationAngle: angle)
}
}
#objc func respondToSwipeLeft(gesture: UIGestureRecognizer) {
let angle = -CGFloat(Double.pi/2)
UIView.animate(withDuration: 0.5) {
self.container.transform = CGAffineTransform(rotationAngle: angle)
}
}
But it completely rotate the container, which is I don't want, I want to make it something like it, and turn back to it's initial position after a sec or two
[![how it should transform][1]][1]
And it would be so awesome that move based on Swiping position, I mean not automatically goes to that level of position, move with finger tip and when it reach there, just stop moving.
Could anyone help me to implement it, I have no idea how I can do it
Many thanks
Adding completion in UIView.animate in order to turn back to initial state. After a sec or two is depends on your duration in UIView.animate
Code will be like this
UIView.animate(withDuration: 0.5, animations: {
self.container.transform = CGAffineTransform(rotationAngle: 0.5)
}, completion: {
_ in
// turn back to the previous before transform
self.container.transform = .identity
})
And for your second question, you can implement with touchesBegan and touchesMoved or add PanGesture to handle changing position container view frame like you want.

smooth animate between 3 locations swift 3

still i'm bignner in swift and ios
i'm building my unversity project, but i faced some issues with animating, firstly here is my code:
#IBAction func tab1(_ sender: Any) {
UIView.animate(withDuration: 0.5, animations:{
self.slider.center.x -= self.tab1.bounds.width
})
}
#IBAction func tab2(_ sender: Any) {
UIView.animate(withDuration: 0.5, animations:{
self.slider.center.x += self.tab2.bounds.width
})
}
#IBAction func tab3(_ sender: Any) {
UIView.animate(withDuration: 0.5, animations:{
self.slider.center.x += self.tab3.bounds.width
})
}
you can see how much it's basic , and there is many problems like if slider in tab1 and click on tab 3 slider will move one step (to tab2) than user needs press one more time, + if you are in tab2 and press on tab2 again slider move again , many bugs in my code, i search for solutions but no luck .
i want adjust it to be animate to correct place and validate it, that means if slider in correct place the slider will not move.
i hope find some help from swift developers
You can just use the button frame to calculate x:
let tab = sender as! UIView
UIView.animate(withDuration: 0.5, animations:{
self.slider.center.x = tab.frame.midX
})

UIScrollView setContentOffset not right

I have an UIScrollView with some labels inside. I can move the scroll view to the other 'page' with an button. But the offset isn't right when I push it too fast.
My code to move the scrollview to the next page:
#IBAction func moveToRight(_ sender: Any) {
let size = Int(scrView.contentOffset.x) + Int(scrView.frame.size.width);
scrView.setContentOffset(CGPoint(x: size, y: 0), animated: true)
}
The offset isn't right when I push it too fast. It looks like that the current animation stops and is going to perform the next one from it's current (unfinished) position.
Does anybody has an solution for this?
I don't have time to test but I think you are on the right track about the main reason of the issue. Since animated is set to true, my guess is contentOffset.x has not yet been set to its ultimate value until animation is finished.
Why don't you change your logic a bit and create a property which remembers the current page at where you last scrolled:
var currentPage: Int = 0
Then every time you moved right, increment the current page number if possible:
#IBAction func moveToRight(_ sender: Any) {
let maxX = scrollView.contentSize.x - scrollView.frame.width
let newX = CGFloat(currentPage + 1) * scrollView.frame.width
if newX <= maxX {
currentPage = currentPage + 1
scrollView.setContentOffset(CGPoint(x: newX, y: 0), animated: true)
}
}

turn animation 180 degrees in swift

I am using a curl up animation when swiping up, which makes a card fly away to the top - it works fine. I'd like to use the same animation, but to swipe down, so that the card flies away down. I guess I'd have to somehow turn the swipe up animation 180 degrees. Is that possible?
let views = (frontView: self.frontView, backView: self.frontView)
// set a transition style
let transitionOptions = UIViewAnimationOptions.TransitionCurlUp
UIView.transitionWithView(self.flashCardView, duration: 0.5, options: transitionOptions, animations: {
views.frontView.removeFromSuperview()
self.flashCardView.addSubview(views.frontView)
}, completion: { finished in
// any code entered here will be applied
})
The UIViewAnimationOptions struct has another option that will solve this for you:
let transitionOptions = UIViewAnimationOptions.TransitionCurlDown

How to drag a SKSpriteNode without touching it with Swift

I'm trying to move SKSpriteNode horizontally by dragging. To get the idea of what I try to achieve you can watch this. I want player to be able to drag sprite without touching it. But I don't really know how to implement it correctly.
I tried to do something like:
override func didMoveToView(view: SKView) {
/* Setup your scene here */
capLeft.size = self.capLeft.size
self.capLeft.position = CGPointMake(CGRectGetMinX(self.frame) + self.capLeft.size.height * 2, CGRectGetMinY(self.frame) + self.capLeft.size.height * 1.5)
capLeft.zPosition = 1
self.addChild(capLeft)
let panLeftCap: UIPanGestureRecognizer = UIPanGestureRecognizer(target: capLeft, action: Selector("moveLeftCap:"))
And when I'm setting a moveLeftCap function, code that I've found for UIPanGestureRecognizer is requiring "View" and gives me an error. I also wanted to limit min and max positions of a sprite through which it shouldn't go.
Any ideas how to implement that?
You probably get that error because you can't just access the view from any node in the tree. You could to refer to it as scene!.view or you handle the gesture within you scene instead which is preferable if you want to keep things simple.
I gave it a try and came up with this basic scene:
import SpriteKit
class GameScene: SKScene {
var shape:SKNode!
override func didMoveToView(view: SKView) {
//creates the shape to be moved
shape = SKShapeNode(circleOfRadius: 30.0)
shape.position = CGPointMake(frame.midX, frame.midY)
addChild(shape)
//sets up gesture recognizer
let pan = UIPanGestureRecognizer(target: self, action: "panned:")
view.addGestureRecognizer(pan)
}
var previousTranslateX:CGFloat = 0.0
func panned (sender:UIPanGestureRecognizer) {
//retrieve pan movement along the x-axis of the view since the gesture began
let currentTranslateX = sender.translationInView(view!).x
//calculate translation since last measurement
let translateX = currentTranslateX - previousTranslateX
//move shape within frame boundaries
let newShapeX = shape.position.x + translateX
if newShapeX < frame.maxX && newShapeX > frame.minX {
shape.position = CGPointMake(shape.position.x + translateX, shape.position.y)
}
//(re-)set previous measurement
if sender.state == .Ended {
previousTranslateX = 0
} else {
previousTranslateX = currentTranslateX
}
}
}
when you move you finger across the screen, the circle gets moves along the x-axis accordingly.
if you want to move the sprite in both x and y directions, remember to invert the y-values from the view (up in view is down in scene).