Swift how to animate fixed uiview from right to left - swift

I'm trying to make my view animate from right to left & change colour unlike the example from dribbble. Currently, my view is moving around the screen not staying fixed to the original position. I'm trying to make it look like this example here but can't seem to make it animate from right to left properly. https://dribbble.com/shots/5690048-Social-Meet-Up-UI-Kit
let options = UIViewAnimationOptions.autoreverse.rawValue | UIViewAnimationOptions.repeat.rawValue | UIViewAnimationOptions.curveEaseInOut.rawValue
UIView.animate(withDuration: 1.0, delay: 0.0, options: UIViewAnimationOptions(rawValue: options), animations: {
// any changes entered in this block will be animated
self.goingBackgrondView.backgroundColor = UIColor.red
self.goingBackgrondView.frame = CGRect(x: 320-50, y: 0, width: 50, height: 55)
}, completion: nil)

That is not move animation. That is resize animation.
Change this:
self.goingBackgrondView.frame = CGRect(x: 320-50, y: 0, width: 50, height: 55)
to this:
self.goingBackgrondView.frame = CGRect(x: 320, y: 0, width: 0, height: 55)

Related

animation not moving upwards in chaining animation in swift

I want my swift code to follow the gif I created. What is going is after the first animation there is not any change of the position. Like the gif I created it should first move down then move up again. I tried multiplying by the negative -0.15 thinking it would go in the north direction. Right now it is not having a effect.
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 0, y: self.view.frame.height * 0.15, width: self.view.frame.width, height: self.view.frame.height * 0.1)
self.block1.center = self.view.center
}) { done in
/// first animation finished, start second
if done {
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 0, y: self.view.frame.height * (-0.15), width: self.view.frame.width, height: self.view.frame.height * 0.1)
self.block1.center = self.view.center
})
}
}
Start by getting rid of self.block1.center = self.view.center as you're making the centre point of the block the same as the view in both cycles.
self.view.frame.height * (-0.15) is setting an absolute position out side of the view, not sure if that's intentional, but you might want to be aware of it. Instead, if you only wanted to move a given distance, say the height of the view, you should be using a relative position, such as block1.frame.origin.y -= block.frame.size.height (probably a much easier way to say that, but you get the idea)
So I created a really quick Playground, made up some values and got a "sort of" bouncy, returny thing going as an example
import UIKit
import XCPlayground
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 300.0, height: 600.0))
// XCPShowView("container", view: container) // -> deprecated
let block1 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: (view.frame.width) / 2, height: 150))
block1.backgroundColor = UIColor.green
block1.center.x = view.center.x
view.addSubview(block1)
UIView.animate(withDuration: 1, animations: {
let y = view.frame.height * 0.15
print(y)
block1.center.y = view.center.y
}) { done in
print("Done = \(done)")
/// first animation finished, start second
if done {
UIView.animate(withDuration: 1, animations: {
block1.frame.origin.y = 0
})
}
}
XCPlaygroundPage.currentPage.liveView = view
Caveat: There's probably a really neat and easy way to do "auto reversal" style animations using CALayer and I'd be keen to see other examples presenting the same concept

UITextField change width when clicking button

I want to make a search field in my app, and I was wondering if it is possible to make it invisible to begin with and then make it appear with the click of a button, like with the magnifying glass in the video below.
I have tried making the width of a UITextField 0 to begin with and then make a button make the width larger, but I am doing something wrong, and I can not figure out what. Maybe you could make an example in a blank project and show/link the code?
I hope you can help :)
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
//change view width
}) { (completed) in
//you can use completion or you can delete I am using it like that
self.searchTextview.becomeFirstResponder()
}
I am using this for my view. You can change for your need. Change constraints or width with animation
Function for expand the SearchTextField
func setTextField(setExpand:Bool = false){
self.txtfldSearch.delegate = self
self.txtfldSearch.borderStyle = UITextField.BorderStyle.none
self.txtfldSearch.translatesAutoresizingMaskIntoConstraints = true
let bottomLine = CALayer()
bottomLine.backgroundColor = UIColor.red.cgColor
UIView.animate(withDuration: 0.5) {
if setExpand{
self.txtfldSearch.frame = CGRect(x:
self.viewContainer.frame.origin.x + 8, y:
self.txtfldSearch.frame.origin.y, width:
(self.btnSearch.frame.origin.x -
(self.viewContainer.frame.origin.x + 16)),
height: self.txtfldSearch.frame.size.height)
bottomLine.frame = CGRect(x: 0.0, y:
self.txtfldSearch.frame.size.height-2, width:
self.txtfldSearch.frame.size.width, height: 2.0)
}
else{
self.txtfldSearch.frame = CGRect(x:
self.btnSearch.frame.origin.x - 8,
y: self.txtfldSearch.frame.origin.y, width: 0,
height:self.txtfldSearch.frame.size.height)
bottomLine.frame = CGRect(x: 0.0, y:
self.txtfldSearch.frame.size.height-2, width:
self.txtfldSearch.frame.size.width, height: 2.0)
}
}
self.txtfldSearch.layer.addSublayer(bottomLine)
}
Use of Code For Expanding pass true and other case pass false
self.setTextField(setExpand: true)

I'm trying to make a card that slides while on swipe in swift

I'm having a hard time with animations and PanGestureRecognizers, I want a view that slides by dragging up or dawn with your finger. It has 4 parts
1 - 2 the height, width and bottom constraints need to be changed
2 - 3 the height is the maximum height and you can slide it in or out
3 - 4 the card is at its maximum height and you can swipe it down
here is an image for a better understanding
thanks!
this is how I would do it.
var theView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// First create your view.
theView = UIView(frame: CGRect(x: 40, y: self.view.bounds.height - 120, width: self.view.frame.width - 80, height: 100))
// set its background color
theView.backgroundColor = UIColor.black
// Create the round corners
theView.layer.cornerRadius = 20
// And add it to the view
self.view.addSubview(theView)
// Create the UIPanGestureRecognizer and assign the function to the selector
let gS = UIPanGestureRecognizer(target: self, action: #selector(growShink(_:)))
// Enable user interactions on the view
theView.isUserInteractionEnabled = true
// Add the gesture recognizer to the view
theView.addGestureRecognizer(gS)
}
// The control value is used to determine wether the user swiped up or down
var controlValue:CGFloat = 0
var animating = false
// The function called when the user swipes
#objc func growShink(_ sender:UIPanGestureRecognizer){
let translation = sender.location(in: theView)
// Check the control value to see if it has been set
if controlValue != 0 && !animating{
// if it has been set check that the control value is greater than the new value recieved by the pan gesture
if translation.x < controlValue{
animating = true
// If it is, change the values of the frame using animate
UIView.animate(withDuration: 0.5, animations: {
self.theView.frame = CGRect(x: 0, y: self.view.bounds.height - 300, width: self.view.frame.width, height: 300)
}, completion: {finished in
UIView.animate(withDuration: 1.0, animations: {
self.theView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
}, completion: {finished in self.animating = false; self.controlValue = 0})})
}else if translation.x > controlValue{
animating = true
// else, change the values of the frame back.
UIView.animate(withDuration: 0.5, animations: {
self.theView.frame = CGRect(x: 0, y: self.view.bounds.height - 300, width: self.view.frame.width, height: 300)
}, completion: {finished in
UIView.animate(withDuration: 1.0, animations: {
self.theView.frame = CGRect(x: 40, y: self.view.bounds.height - 120, width: self.view.frame.width - 80, height: 100)
}, completion: {finished in self.animating = false; self.controlValue = 0})})
}
}
// set the control value to the value received from the pan gesture
controlValue = translation.x
}
}
You can adjust the width and height values however you want.

Filling animation + permanent mask in swift?

Something like this:
Or follow this link if you can:
https://www.lottiefiles.com/450-play-fill-loader
My case is simpler - I have a view with mask which consists of multiple rects and a linear fill. Mask is created in runtime (so I can't use lottie) but remains permanent, fill is animated (filling from right to left). But how to draw it?
Note: I tried to find a similar animation implementation but in most cases they just try to change the mask params while in my case mask is constant.
If i understand you correct, you can add subview under your mask and change its width, something like that:
let fillingStartFrame = CGRect.init(x: 0, y: 0, width: 0, height: view.frame.height)
let fillingEndFrame = CGRect.init(x: 0, y: 0, width: view.frame.width, height: view.frame.width)
let fillingView = UIView(frame: fillingStartFrame)
view.insertSubview(fillingView, belowSubview: YOUR_MASK)
UIView.animate(withDuration: 0.3) {
fillingView.frame = fillingEndFrame
}

UIView sizing programmatically

I have an UIView with two containers in IB with two filter buttons (one is up and one is down). I have created two functions called filterUP and filterDOWN and they work like this :
#IBAction func FilterDown(sender: AnyObject) {
self.FilterDownButton.hidden = true
var duration = 0.5
self.FilterView.clipsToBounds = true
UIView.animateWithDuration(duration, animations: {
self.FilterView.frame = CGRect(x: 0, y: 65, width: 375, height: 195)
}, completion: { finished in
self.FilterUPButton.hidden = false
self.FilterDownButton.hidden = false
})
And what it does is animate the filter UIView up and down. which is fine and they work.
When the app starts I want the UIView (filter) at CGRect(x: 0, y: 65, width: 375, height: 65) - i.e. hidden only 20 high.
So I did
self.view.frame = CGRect(x:0, y:65, width: 375, height: 20)
in viewDidLoad.
This has not done anything and the UIView is still full size when the app runs.
I have toggled with AutoLayout (On/Off) and Size Classes (on/Off) and this does not work.
How can I get the UIView a certain size when the app starts up ?