UIView sizing programmatically - swift

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 ?

Related

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.

Swift how to animate fixed uiview from right to left

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)

Add subView behind items to UINavigationBar in iOS 11

In my UINavigationBar subclass I am adding a subView with insertSubview(customView, at: 0) in order to place it in the very 'back' of the UINavigationBar.
In iOS 10 the added subView will be added the Title and UIBarButtonItems as I want it, but in in iOS 11 it seems like Apple changed something because no matter what I try the customView will be placed every time in the front of the UINavigationBar.
//containerView
containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)
containerView.clipsToBounds = true
insertSubview(containerView, at: 0)
I already tried changing the index.
Any idea how I should tackle that problem?
You can look at this. I solved it this way:
override func layoutSubviews() {
super.layoutSubviews()
for aView in self.subviews {
if NSStringFromClass(type(of: aView)) == "_UINavigationBarContentView" {
aView.frame = CGRect(x: 0, y: 20, width: aView.frame.width, height: aView.frame.height)
}
else if NSStringFromClass(type(of: aView)) == "_UIBarBackground" {
aView.frame = CGRect(x: 0, y: 0, width: aView.frame.width, height: self.frame.height)
}
}
}

UIView Orientation change in Swift

I'm developing an app to display a binary tree.
Each node will be displayed as a subview programatically generated from the ViewController - I run the following from viewDidLayoutSubviews().
let theView = BinaryTreeView(frame: CGRect(x: 0, y: 50, width: width, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
theView.backgroundColor = .white
theView.addGestureRecognizer(UIPinchGestureRecognizer(target:theView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(theView)
theView.eyesOpen = false
let secondView = BinaryTreeView(frame: CGRect(x: width/2, y: 150, width: width/2, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
secondView.backgroundColor = .white
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:secondView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(secondView)
let thirdView = BinaryTreeView(frame: CGRect(x: (width/2)+width/4, y: 250, width: width/4, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
thirdView.backgroundColor = .white
thirdView.addGestureRecognizer(UIPinchGestureRecognizer(target:thirdView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(thirdView)
The issue is that on orientation change the views repeat each other (above there are three nodes, on orientation change 4 might display.
I looked through Stack and Within my subclassed UIView I added:
self.contentMode = UIViewContentMode.redraw
Within the programatic Subview but the same happens.
Don't worry - I'm going to generate my nodes in a loop later (I'm trying to understand how layout works). Incidentally I found the same happened using a UICollectionView so I seem to be doing something fundamentally wrong.
Change the "target:" to the controller (to self) for all three. Your controller will respond to gestures, not the views themselves. The target will be the same in all three cases.
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:secondView, action:#selector(BinaryTreeView.changeScale)))
self.view.addSubview(secondView)
becomes
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:self, action:#selector(BinaryTreeView.changeScale)))
self.view.addSubview(secondView)