How to transform multiple view to same location(CGPoint) - ios

I've got multiple UIImageViews, spread across in a view.
#IBOutlet var leftIVs: [UIImageView]!
#IBOutlet var topIVs: [UIImageView]!
#IBOutlet var rightIVs: [UIImageView]!
I'm trying to create a function using UIView.animate... functions and 'transform' property which brings all of these UIImageViews at the center of the superview. I'm using the following code:
let performInitialTransformation: ((UIImageView)->()) = { (card) in
let cardCenter = CGPoint(x: card.frame.midX, y: card.frame.midY)
let viewCenter = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
let deltaPoint = cardCenter - viewCenter //also tried (viewCenter - cardCenter)
UIView.animate(withDuration: 0.5, animations: {
card.transform = CGAffineTransform.init(translationX: deltaPoint.x, y: deltaPoint.y)
}) { (done) in
}
}
for card in topIVs {
performInitialTransformation(card)
}
for card in leftIVs {
performInitialTransformation(card)
}
for card in rightIVs {
performInitialTransformation(card)
}
I'm using this static function:
extension CGPoint {
static func -(lhs: CGPoint, rhs: CGPoint) -> CGPoint {
return CGPoint(x: rhs.x - lhs.x, y: rhs.y - lhs.y)
}
}
NOTE: Also, I will be bringing those images back to there original position afterward for which I will use CGAffineTransform.identity
The images are not being shown in the center. How can I achieve this? Thanks in advance!

I think your problem was that you didn't reduce the size of the image view so that they stack at the exact centre of the screen.
let deltaX = (self.view.center.x - card.frame.minX) - card.frame.width/2
let deltaY = (self.view.center.y - card.frame.minY) - card.frame.height/2
UIView.animate(withDuration: 1) {
card.transform = .init(translationX: deltaX, y: deltaY)
}

What is about to use center
UIView.animate(withDuration: 0.5) {
images.forEach { $0.center = superview.center }
}
The full example
var subviewes = [UIView]()
var view = UIView(frame: CGRect.init(x: 0, y: 0, width: 30, height: 30))
view.backgroundColor = .yellow
subviewes.append(view)
view = UIView(frame: CGRect.init(x: 0, y: 0, width: 20, height: 20))
view.backgroundColor = .green
subviewes.append(view)
view = UIView(frame: CGRect.init(x: 0, y: 0, width: 10, height: 10))
view.backgroundColor = .red
subviewes.append(view)
subviewes.forEach { self.view.addSubview($0) }
UIView.animate(withDuration: 0.5) {
subviewes.forEach { $0.center = self.view.center }
}

Related

Swift - Problem with scrollview (Need to print when dragging down)

I am testing the swiping controller/gesture from Jake Spracher with his SnapchatSwipeView (https://github.com/jakespracher/Snapchat-Swipe-View )
I have setup a topVC,leftVC,rightVC and middleVC(the main VC).
I manage to capture when the user swipe from the center to the rightVC or to the left VC, with this :
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if delegate != nil && !delegate!.outerScrollViewShouldScroll() && !directionLockDisabled {
let newOffset = CGPoint(x: self.initialContentOffset.x, y: self.initialContentOffset.y)
self.scrollView!.setContentOffset(newOffset, animated: false)
}
if (scrollView.contentOffset) == CGPoint(x: 750.0, y: 0.0) {
print ("TEST OK LEFT!")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "loadRinkbox"), object: nil)
}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 0.0) {
print ("TEST OK LEFT!")
}
if (scrollView.contentOffset) == CGPoint(x: -750.0, y: 0.0) {
print ("TEST OK RIGHT")
}
if (scrollView.contentOffset) == CGPoint(x: 375, y: 0.0) {
print ("TEST OK!")
}
}
But I cannot manage to capture when the user swipe from the centerVC to the topVC, and from topVC to centerVC. I have tried a lot of things but I didn't manage to do it.
My code is for swift 4.
For clarity, I put here the two full swift files. Many, million thanks for those that can help me !
ContainerViewController.swift
//
// ContainerViewController.swift
// SnapchatSwipeView
//
// Created by Jake Spracher on 8/9/15.
// Copyright (c) 2015 Jake Spracher. All rights reserved.
//
import UIKit
import AVFoundation
protocol SnapContainerViewControllerDelegate {
// print "Snapcontainerview"
func outerScrollViewShouldScroll() -> Bool
}
class SnapContainerViewController: UIViewController, UIScrollViewDelegate {
var captureSession : AVCaptureSession!
private var current: UIViewController
// print "2"
var deeplink: DeeplinkType? {
didSet {
handleDeeplink()
}
}
init() {
current = SplashViewController()
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var topVc: UIViewController?
var leftVc: UIViewController!
var middleVc: UIViewController!
var rightVc: UIViewController!
var bottomVc: UIViewController?
var directionLockDisabled: Bool!
var horizontalViews = [UIViewController]()
var veritcalViews = [UIViewController]()
var initialContentOffset = CGPoint() // scrollView initial offset
var middleVertScrollVc: VerticalScrollViewController!
var scrollView: UIScrollView!
var delegate: SnapContainerViewControllerDelegate?
class func containerViewWith(_ leftVC: UIViewController,
middleVC: UIViewController,
rightVC: UIViewController,
topVC: UIViewController?=nil,
bottomVC: UIViewController?=nil,
directionLockDisabled: Bool?=false) -> SnapContainerViewController {
let container = SnapContainerViewController()
container.directionLockDisabled = directionLockDisabled
container.topVc = topVC
container.leftVc = leftVC
container.middleVc = middleVC
container.rightVc = rightVC
container.bottomVc = bottomVC
return container
}
var scrollOffSetClosure: ((_ offset: CGFloat) -> Void)?
// code truncated for brevity
func scrollViewDidScroll2(_ scrollView: UIScrollView) {
scrollOffSetClosure!(scrollView.contentOffset.x)
print("test here")
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
print("end scroll")
}
override func viewDidLoad() {
super.viewDidLoad()
addChildViewController(current)
current.view.frame = view.bounds
view.addSubview(current.view)
current.didMove(toParentViewController: self)
}
func setupVerticalScrollView() {
middleVertScrollVc = VerticalScrollViewController.verticalScrollVcWith(middleVc: middleVc as! Camera,
topVc: topVc,
bottomVc: bottomVc)
delegate = middleVertScrollVc
}
func setupHorizontalScrollView() {
scrollView = UIScrollView()
scrollView.isPagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.bounces = false
print ("6")
let view = (
x: self.view.bounds.origin.x,
y: self.view.bounds.origin.y,
width: self.view.bounds.width,
height: self.view.bounds.height
)
scrollView.frame = CGRect(x: view.x,
y: view.y,
width: view.width,
height: view.height
)
self.view.addSubview(scrollView)
let scrollWidth = 3 * view.width
let scrollHeight = view.height
scrollView.contentSize = CGSize(width: scrollWidth, height: scrollHeight)
leftVc.view.frame = CGRect(x: 0,
y: 0,
width: view.width,
height: view.height
)
middleVertScrollVc.view.frame = CGRect(x: view.width,
y: 0,
width: view.width,
height: view.height
)
rightVc.view.frame = CGRect(x: 2 * view.width,
y: 0,
width: view.width,
height: view.height
)
addChildViewController(leftVc)
addChildViewController(middleVertScrollVc)
addChildViewController(rightVc)
scrollView.addSubview(leftVc.view)
scrollView.addSubview(middleVertScrollVc.view)
scrollView.addSubview(rightVc.view)
leftVc.didMove(toParentViewController: self)
middleVertScrollVc.didMove(toParentViewController: self)
rightVc.didMove(toParentViewController: self)
scrollView.contentOffset.x = middleVertScrollVc.view.frame.origin.x
scrollView.delegate = self
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
// print ("Scrollviewvillbegindragging scrollView.contentOffset \(scrollView.contentOffset)")
self.initialContentOffset = scrollView.contentOffset
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if delegate != nil && !delegate!.outerScrollViewShouldScroll() && !directionLockDisabled {
let newOffset = CGPoint(x: self.initialContentOffset.x, y: self.initialContentOffset.y)
// print(newOffset.x)
//print(newOffset.y)
// Setting the new offset to the scrollView makes it behave like a proper
// directional lock, that allows you to scroll in only one direction at any given time
self.scrollView!.setContentOffset(newOffset, animated: false)
// print ("newOffset \(newOffset)")
// tell child views they have appeared / disappeared
}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 667.0) {print ("aaa!")}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: -667.0) {print ("bbb!")}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 375) {print ("aaccca!")}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: -375) {print ("ddddd!")}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 0.0) {print ("eeeeeee!")}
// if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 667.0) {print ("ffffff!")}
// if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 667.0) {print ("aggggggggaa!")}
// print ("scrollViewDidScroll scrollView.contentOffset \(scrollView.contentOffset)")
// scrollView.contentOffset
if (scrollView.contentOffset) == CGPoint(x: 750.0, y: 0.0) {
print ("TEST OK LEFT!")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "loadRinkbox"), object: nil)
}
if (scrollView.contentOffset) == CGPoint(x: 0.0, y: 0.0) {
print ("TEST OK RIGHT!")
}
if (scrollView.contentOffset) == CGPoint(x: -750.0, y: 0.0) {
print ("TEST OK LEFT")
}
if (scrollView.contentOffset) == CGPoint(x: 375, y: 0.0) {
print ("TEST LEFT/RIGHT OK!")
}
}
private func animateFadeTransition(to new: UIViewController, completion: (() -> Void)? = nil) {
print ("Ca va dans animateFadeTransition")
current.willMove(toParentViewController: nil)
addChildViewController(new)
transition(from: current, to: new, duration: 0.3, options: [.transitionCrossDissolve, .curveEaseOut], animations: {
}) { completed in
self.current.removeFromParentViewController()
new.didMove(toParentViewController: self)
self.current = new
completion?()
}
}
private func animateDismissTransition(to new: UIViewController, completion: (() -> Void)? = nil) {
print ("Ca va dans animateDismissTransition")
let initialFrame = CGRect(x: -view.bounds.width, y: 0, width: view.bounds.width, height: view.bounds.height)
current.willMove(toParentViewController: nil)
addChildViewController(new)
new.view.frame = initialFrame
transition(from: current, to: new, duration: 0.3, options: [], animations: {
new.view.frame = self.view.bounds
}) { completed in
self.current.removeFromParentViewController()
new.didMove(toParentViewController: self)
self.current = new
completion?()
}
}
}
and VerticalScrollViewController
/ MiddleScrollViewController.swift
// SnapchatSwipeView
//
// Created by Jake Spracher on 12/14/15.
// Copyright © 2015 Jake Spracher. All rights reserved.
//
import UIKit
class VerticalScrollViewController: UIViewController, SnapContainerViewControllerDelegate {
var topVc: UIViewController!
var middleVc: UIViewController!
var bottomVc: UIViewController!
var scrollView: UIScrollView!
class func verticalScrollVcWith(middleVc: UIViewController,
topVc: UIViewController?=nil,
bottomVc: UIViewController?=nil) -> VerticalScrollViewController {
let middleScrollVc = VerticalScrollViewController()
middleScrollVc.topVc = topVc
middleScrollVc.middleVc = middleVc
middleScrollVc.bottomVc = bottomVc
return middleScrollVc
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view:
setupScrollView()
}
func setupScrollView() {
scrollView = UIScrollView()
scrollView.isPagingEnabled = true
scrollView.showsVerticalScrollIndicator = false
scrollView.bounces = false
let view = (
x: self.view.bounds.origin.x,
y: self.view.bounds.origin.y,
width: self.view.bounds.width,
height: self.view.bounds.height
)
scrollView.frame = CGRect(x: view.x, y: view.y, width: view.width, height: view.height)
self.view.addSubview(scrollView)
let scrollWidth: CGFloat = view.width
var scrollHeight: CGFloat
switch (topVc, bottomVc) {
case (nil, nil):
scrollHeight = view.height
middleVc.view.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)
addChildViewController(middleVc)
scrollView.addSubview(middleVc.view)
middleVc.didMove(toParentViewController: self)
case (_?, nil):
scrollHeight = 2 * view.height
topVc.view.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)
middleVc.view.frame = CGRect(x: 0, y: view.height, width: view.width, height: view.height)
addChildViewController(topVc)
addChildViewController(middleVc)
scrollView.addSubview(topVc.view)
scrollView.addSubview(middleVc.view)
topVc.didMove(toParentViewController: self)
middleVc.didMove(toParentViewController: self)
scrollView.contentOffset.y = middleVc.view.frame.origin.y
case (nil, _?):
scrollHeight = 2 * view.height
middleVc.view.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)
bottomVc.view.frame = CGRect(x: 0, y: view.height, width: view.width, height: view.height)
addChildViewController(middleVc)
addChildViewController(bottomVc)
scrollView.addSubview(middleVc.view)
scrollView.addSubview(bottomVc.view)
middleVc.didMove(toParentViewController: self)
bottomVc.didMove(toParentViewController: self)
scrollView.contentOffset.y = 0
default:
scrollHeight = 3 * view.height
topVc.view.frame = CGRect(x: 0, y: 0, width: view.width, height: view.height)
middleVc.view.frame = CGRect(x: 0, y: view.height, width: view.width, height: view.height)
bottomVc.view.frame = CGRect(x: 0, y: 2 * view.height, width: view.width, height: view.height)
addChildViewController(topVc)
addChildViewController(middleVc)
addChildViewController(bottomVc)
scrollView.addSubview(topVc.view)
scrollView.addSubview(middleVc.view)
scrollView.addSubview(bottomVc.view)
topVc.didMove(toParentViewController: self)
middleVc.didMove(toParentViewController: self)
bottomVc.didMove(toParentViewController: self)
scrollView.contentOffset.y = middleVc.view.frame.origin.y
}
scrollView.contentSize = CGSize(width: scrollWidth, height: scrollHeight)
}
// MARK: - SnapContainerViewControllerDelegate Methods
func outerScrollViewShouldScroll() -> Bool {
if scrollView.contentOffset.y < middleVc.view.frame.origin.y || scrollView.contentOffset.y > 2*middleVc.view.frame.origin.y {
return false
} else {
return true
}
}
}
In MiddleScrollViewController.swift, make the controller conform to UIScrollViewDelegate:
class VerticalScrollViewController: UIViewController,
SnapContainerViewControllerDelegate,
UIScrollViewDelegate {
In that class, in setupScrollView(), set the delegate:
func setupScrollView() {
scrollView = UIScrollView()
// set the delegate to self
scrollView.delegate = self
// the rest of the existing code...
Still in that class, implement didScroll (or whatever other delegate funcs you want to handle):
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("Vertical Scroll - contentOffset:", scrollView.contentOffset)
}
Now you should get lots of print lines in the debug console when you scroll vertically:
Vertical Scroll - contentOffset: (0.0, 561.0)
Vertical Scroll - contentOffset: (0.0, 560.0)
Vertical Scroll - contentOffset: (0.0, 559.0)
Vertical Scroll - contentOffset: (0.0, 558.0)
If you want your SnapContainerViewController class to be informed when vertical scrolling takes place, you'll probably want to use a new protocol/delegate so VerticalScrollViewController can send that information.

Why my UILabel doesn't conforms to the inital frame?

I'm trying to create a popup label over the imageview. But in my application it doesn't work. I've made a test application with the same screen: UIImageView and below a UIView with a UIButton on the view.
So, where are two questions.
What could be difference in a code for such a different behaviour?
Why in my application the UILabel doesn't conforms to the initial frame?
The code of the function inside my viewController is the same:
private func showBanner(startY: CGFloat, targetView: UIView) {
let height: CGFloat = 42
let finishY = startY - height
let bannerLabel = UILabel(frame: CGRect(x: 0, y: startY, width: self.view.frame.width, height: height))
bannerLabel.translatesAutoresizingMaskIntoConstraints = false
bannerLabel.font = UIFont.systemFont(ofSize: 13, weight: .regular)
bannerLabel.textColor = .lightGray
bannerLabel.backgroundColor = .black
bannerLabel.textAlignment = .center
bannerLabel.numberOfLines = 1
bannerLabel.text = "You've added the item to the favorites"
targetView.addSubview(bannerLabel)
UIView.animate(withDuration: 0.5, animations: {
bannerLabel.frame = CGRect(x: 0,
y: finishY,
width: self.view.frame.width,
height: height
)
}) {
_ in
UIView.animate(withDuration: 0.5, delay: 1.0, options: .curveLinear, animations: {
bannerLabel.frame = CGRect(x: 0,
y: startY,
width: self.view.frame.width,
height: height
)
}, completion: {
_ in
bannerLabel.removeFromSuperview()
})
}
}
The function is being called so:
showBanner(startY: itemsImageView.frame.maxY, targetView: itemsImageView)
The problem was in the line:
bannerLabel.translatesAutoresizingMaskIntoConstraints = false
As soon as this line was removed, the problem has dissapeared.

Touch event on Visible Portion of Views ios swift 4

I am working of Photo Collage which is in Swift4 , I had created collage using UIBezierPath as Below
I have 5 scroll views in Storyboard and the sequence of Scrollviews as Below
Using Following code I am creating Shapes :
var path1 = UIBezierPath()
path1.move(to: CGPoint(x: 0, y: 0))
path1.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
path1.addLine(to: CGPoint(x: 0, y: superView.frame.width / 2))
path1.addLine(to: CGPoint(x: 0, y: 0))
var borderPathRef1 = path1.cgPath
var borderShapeLayer1 = CAShapeLayer()
borderShapeLayer1.path = borderPathRef1
scroll1.layer.mask = borderShapeLayer1
scroll1.layer.masksToBounds = true
var path2 = UIBezierPath()
path2.move(to: CGPoint(x: 0, y: 0))
path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: 0))
path2.addLine(to: CGPoint(x: superView.frame.width / 2, y: superView.frame.width / 2))
path2.addLine(to: CGPoint(x: 0, y: 0))
var borderPathRef2 = path2.cgPath
var borderShapeLayer2 = CAShapeLayer()
borderShapeLayer2.path = borderPathRef2
scroll2.layer.mask = borderShapeLayer2
scroll2.layer.masksToBounds = true
Now the issue is I am not able to get touch event of Scrollviews as Scroll5 is on top. I want to get Touch on Overlapped views like Scroll1, Scroll2 and so on. In Short I need touch event for particular view on the portion of area where the view is visible.
See The Image Below Where I want Touch for Views.
How can I get touch on Overlapped Views?
Please Help!
You have to be sure that you set the superView of scrollview to isUserInterfaceEnabled=true first.
To get overlapped views touch event:
here is my code:
class CustomView: UIView {
let view1: UIView
let view2: UIView
let view3: UIView
let view4: UIView
let view5: UIView
override init(frame: CGRect) {
view1 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view1.backgroundColor = UIColor.black
view1.isUserInteractionEnabled = true
view2 = UIView(frame: CGRect(x: 100, y: 0, width: 100, height: 100))
view2.backgroundColor = UIColor.orange
view2.isUserInteractionEnabled = true
view3 = UIView(frame: CGRect(x: 0, y: 100, width: 100, height: 100))
view3.backgroundColor = UIColor.blue
view3.isUserInteractionEnabled = true
view4 = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view4.backgroundColor = UIColor.brown
view4.isUserInteractionEnabled = true
view5 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view5.tag = 121
view5.backgroundColor = UIColor.red
super.init(frame: frame)
self.addSubview(view1)
self.addSubview(view2)
self.addSubview(view3)
self.addSubview(view4)
self.addSubview(view5)
view1.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(touchAction)))
}
#objc func touchAction () {
print("----------- touch view 1")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (view1.point(inside: self.convert(point, to: view1), with: event)) {
return view1
}
return self
}
}
The function hitTest decides that which view you are touching, so you just need to return the overlapped view.

How to scale a UIView from left to right and back?

I want to have an UIView to appear by scaling from left to right if I hit a button. If I hit the button again, the view should scale away from right to left.
I found an explanation how to do it for left to right, but even this solution is working only once. If I hide the view and play the animation again it scales it from the centre again.
Also scaling it back from right to left doesn't work either as it disappears immdiatly without any animation.
Here's my code so far:
if(!addQuestionaryView.isHidden)
{
//Reset input if view is hidden
addQuestionaryInput.text = ""
self.addQuestionaryView.isHidden = false
let frame = addQuestionaryView.frame;
let rect = CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.width, height: frame.height)
let leftCenter = CGPoint(x: rect.minX, y: rect.minY)
addQuestionaryView.layer.anchorPoint = CGPoint(x:1,y: 0.5)
addQuestionaryView.layer.position = leftCenter
UIView.animate(withDuration: 0.6,
animations: {
self.addQuestionaryView.transform = CGAffineTransform(scaleX: 0, y: 1)
},
completion: { _ in
self.addQuestionaryView.isHidden = true
})
}
else
{
self.addQuestionaryView.isHidden = false
let frame = addQuestionaryView.frame;
let rect = CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.width, height: frame.height)
let leftCenter = CGPoint(x: rect.minX, y: rect.midY)
addQuestionaryView.layer.anchorPoint = CGPoint(x:0,y: 0.5);
addQuestionaryView.layer.position = leftCenter
addQuestionaryView.transform = CGAffineTransform(scaleX: 0, y: 1)
UIView.animate(withDuration: 0.6,
animations: {
self.addQuestionaryView.transform = CGAffineTransform(scaleX: 1, y: 1)
},
completion: nil)
}
As said the appearing part works once and then starts from the centre again. The disappearing part doesn't work at all.
I don't know what "to scale it so it has a little look like Android reveal animations" means (and I hope I never do; I've never seen an Android phone, I never hope to see one).
But do you mean something like this? This is done by animating a mask in front of the view, thus revealing and then hiding it:
Here's the code used in that example:
class MyMask : UIView {
override func draw(_ rect: CGRect) {
let r = CGRect(x: 0, y: 0, width: rect.width/2.0, height: rect.height)
UIColor.black.setFill()
UIGraphicsGetCurrentContext()?.fill(r)
}
}
class ViewController: UIViewController {
#IBOutlet weak var lab: UILabel!
var labMaskOrigin = CGPoint.zero
var didAddMask = false
override func viewDidLayoutSubviews() {
if didAddMask {return}
didAddMask = true
let mask = MyMask()
mask.isOpaque = false
let w = self.lab.bounds.width
let h = self.lab.bounds.height
mask.frame = CGRect(x: -w, y: 0, width: w*2, height: h)
self.lab.mask = mask
self.labMaskOrigin = mask.frame.origin
}
var labVisible = false
func toggleLabVisibility() {
labVisible = !labVisible
UIView.animate(withDuration: 5) {
self.lab.mask!.frame.origin = self.labVisible ?
.zero : self.labMaskOrigin
}
}
}
Remove this:
addQuestionaryView.layer.anchorPoint = CGPoint(x:0,y: 0.5);
addQuestionaryView.layer.position = leftCenter
addQuestionaryView.transform = CGAffineTransform(scaleX: 0, y: 1)
Then in your animate with duration block use the code below instead of CGAfflineTransform
addQuestionaryView.frame = CGRect(0,0,500,100)
Replace 500 width whatever width you want it to be.
Ans to close it back up do this:
addQuestionaryView.frame = CGRect(0,0,0,100);

Why the "RemoveAllAnimations()" doesn't stop my animation?

I have a very simple sample that allows to drag an UIView around. When touch up, I will have an inertia effect on the dragging direction for a second. While if I touch down again, I need to stop all the inertia animation and start to do another drag. Here is my code, the "clearAllAnimations" doesn't stop my animation. How could I implement that?
import UIKit
class ViewController: UIViewController {
var tile : UIView = UIView()
var labelView = UITextView()
var displayLink : CADisplayLink?
override func viewDidLoad() {
super.viewDidLoad()
tile.frame = CGRect(x: 0, y: 0, width: 256, height: 256)
tile.backgroundColor = UIColor.redColor()
view.addSubview(tile)
var panGesture = UIPanGestureRecognizer(target: self, action: Selector("panHandler:"))
view.addGestureRecognizer(panGesture)
labelView.frame = CGRect(x: 0, y: 100, width: view.frame.width, height: 44)
labelView.backgroundColor = UIColor.clearColor()
view.addSubview(labelView)
}
func panHandler (p: UIPanGestureRecognizer!) {
var translation = p.translationInView(view)
if (p.state == UIGestureRecognizerState.Began) {
self.tile.layer.removeAllAnimations()
}
else if (p.state == UIGestureRecognizerState.Changed) {
var offsetX = translation.x
var offsetY = translation.y
var newLeft = tile.frame.minX + offsetX
var newTop = tile.frame.minY + offsetY
self.tile.frame = CGRect(x: newLeft, y: newTop, width: self.tile.frame.width, height: self.tile.frame.height)
labelView.text = "x: \(newLeft); y: \(newTop)"
p.setTranslation(CGPoint.zeroPoint, inView: view)
}
else if (p.state == UIGestureRecognizerState.Ended) {
var inertia = p.velocityInView(view)
var offsetX = inertia.x * 0.2
var offsetY = inertia.y * 0.2
var newLeft = tile.frame.minX + offsetX
var newTop = tile.frame.minY + offsetY
UIView.animateWithDuration(1, delay: 0, options:UIViewAnimationOptions.CurveEaseOut, animations: {_ in
self.tile.frame = CGRect(x: newLeft, y: newTop, width: self.tile.frame.width, height: self.tile.frame.height)
}, completion: nil)
}
}
}
Setting UIViewAnimationOptions.AllowUserInteraction does the trick. The new code to start animation is this:
UIView.animateWithDuration(animationDuration, delay: 0, options:UIViewAnimationOptions.CurveEaseOut | UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.BeginFromCurrentState, animations: {_ in
self.tile.frame = CGRect(x: newLeft, y: newTop, width: self.tile.frame.width, height: self.tile.frame.height)
}, completion: nil)

Resources