Using a slider to transition between 2 images - swift

I am trying to learn the basics, but still very new to Xcode and Swift. I want to use a slider to transition between two images. When the slider is all the way to the left, image 1 should show in the image view. As the slider moves to the right, image 1 should fade and an image 2 should come into view. At the halfway point, both images should be visible (alpha = 0.5 for both image), superimposed one on top of the other. As the slider goes all the way to the right, image 1 should vanish and image 2 should be the only one visible.
Using UIImageView and a slider, I am able to adjust the alpha and "fade" my image based on the position of the slider.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var UAimage: UIImageView!
#IBOutlet weak var Slider: UISlider!
#IBAction func sliderValueChange(_ sender: UISlider) {
var currentValue = Float(sender.value)
UAimage.alpha = CGFloat(sender.value)
}
}
At this point, I am looking for help getting the second image added and using alpha to programmatically control its opacity.

Just add a 2nd imageview over the first and add this line
imageview2.alpha = CGFloat(1 - sender.value)

import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var UAimage: UIImageView!
/*
Your 2nd image.
On storyboard, go place a UIImageView directly on top of your initial imageView and set the image to whatever you'd like just as you did the original.
*/
#IBOutlet weak var UAimage2: UIImageView! //Your 2nd image
#IBOutlet weak var Slider: UISlider!
#IBAction func sliderValueChange(_ sender: UISlider) {
var currentValue = Float(sender.value)
UAimage.alpha = CGFloat(sender.value)
UAimag2.alpha = 1 - CGFloat(sender.value)
}
}

Related

UIView's animate method not appearing

I am trying to make an app that utilizes some search feature and I am trying to make it so that after the search button is pressed, a view (which contains the search results) moves up from the bottom of the superview and replaces the search view. On the storyboard, the resultsView (of type UIView) is constrained so that its top is equal to the superview's bottom. After the search button is pressed, I would like to animate the view to move up and replace the view already at the bottom of the superview. The problem is, in the viewcontroller's class, when I call the resultsView, the animateWithDuration(NSTimeInterval) that is supposed to be associated with the UIView class is not appearing for me. May this be because the view is already constrained in place? Here is the code, simplified for this post:
import UIKit
import MapKit
class MapViewController: UIViewController, CLLocationManagerDelegate,
MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var distanceLabel: UILabel!
#IBOutlet weak var searchButton: UIButton!
#IBOutlet weak var searchView: UIView!
#IBOutlet weak var resultView: UIView!
#IBOutlet weak var resultNameLabel: UILabel!
#IBOutlet weak var resultDistanceLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
self.resultView.isHidden = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func sliderAdjusted(_ sender: Any) {
let int = Int(slider.value)
switch int {
case 1:
distanceLabel.text = "1 mile"
default:
distanceLabel.text = "\(int) miles"
}
}
#IBAction func searchButtonPressed(_ sender: Any) {
/*This is where, after calling a search function which is omitted
from this example, I would like to make the resultsView not
hidden and then animate it to sort of eclipse the search view*/
self.resultView.isHidden = false
self.resultView.animate(withDuration: NSTimeInterval)
/*The above line of code is not actually appearing for me.
After typing "self.resultView." the animate function is not being
given to me as an option for my UIView*/
}
}
I will also attach some images of the view controller so you can sort of get the idea. The results view is not visible in this image because its top is constrained to the superview's bottom, thus it is just out of the visible representation of its superview.
The first image is the view controller with the searchView highlighted. This is the view that I would like to be eclipsed by my resultView after the searchButton is pressed.
The second image is the same view controller with the resultView highlighted. As you can see, its top is constrained to be equal to the superview's bottom. This is the view that I would like to animate upwards into the superview and eclipse the searchView after the search button is pressed.
The methods for all the animate family are all class methods. Which means you call them on the class object not an instance.
You are trying to call
class func animate(withDuration: TimeInterval, animations: () -> Void)
so your code needs to look like
UIView.animate(withDuration: 0.5) {
//the things you want to animate
//will animate with 0.5 seconds duration
}
In the particular case it looks like you are trying to animate the height of resultView so you need an IBOutlet to that constraint. You could call it resultViewHeight.
UIView.animate(withDuration: 0.5) {
self.resultViewHeight.constant = theDesiredHeight
self.layoutIfNeeded()
}
Calling layoutIfNeeded() within the closure is the secret sauce to animating auto layout. Without that the animation will just jump to the and point.

how to set background colour of a container view

i have dragged a container view from storyboard and set it black in background colour. but it didn't change the background colour.
class ViewController: UIViewController {
#IBOutlet weak var container: UIView!
override func viewDidLoad() {
super.viewDidLoad()
container.layer.backgroundColor = UIColor.blackColor().CGColor
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
How did you set the background color?
A container view is actually just a normal view, that is linked to a viewController. This means you can set the background the same way as you would for any other NSView or UIView. This is all the code I needed to add to my NSViewController class (not the ViewController inside the container, just the ViewController for the window).
#IBOutlet weak var containerView: NSView!
override func viewDidLoad() {
//other code in your viewDidLoad
containerView.wantsLayer = true
}
override func awakeFromNib() {
super.awakeFromNib()
containerView.layer?.backgroundColor = NSColor.black.cgColor
}
make sure to connect the IBOutlet if you have not already.
If you set the layers background color in viewDidLoad, the layer may not exist yet, (I don't know why). Accessing the layer in awakeFromNib has always worked for me, while accessing it in the viewDidLoad can be unreliable.
If you are working on IOS, most of this is not applicable, and this should be all you need
#IBOutlet weak var containerView: UIView!
override func viewDidLoad() {
containerView.layer?.backgroundColor = UIColor.black.cgColor
}
I work less on IOS, so I have not ran into any issues with that, but that could be from lack of attempts. On OSX setting the background color in viewDidLoad will work about 50% of the time so there might still be an issue that I have not ran into.
If neither works, try unwrapping the layer rather than leaving it an optional (replacing the ? with a !) this will at least crash your program and probably tell you that layer is nil, if this is the case you should be figuring out why the layer is nil.
Also if the ViewController connected to the container view is a custom class, you don't have to bother with the IBOutlets, just call the view "view" in that custom class.
Sorry this got a bit long, but hope this helped

viewWillAppear method doesn't work

import UIKit
class ViewController: UIViewController {
#IBOutlet weak var family_name: UITextField!
#IBOutlet weak var given_name: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
family_name.center.x -= view.bounds.width
given_name.center.x -= view.bounds.width
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
viewWillAppear has no effect. When I run my app both text fields shouldn't be visible, but they are. I attached a photo with constraints; I think this can be the problem!
You are using autolayout, so frame change will not apply. your constraints will overwrite frame values after viewWillAppear:
Create IBOutlet for either right constraint or width constraint of your textFields.
Check below sample image to create IBOutlet of constraint.
In above image I have create outlet of height constraint.
To send textField outside of the view, suppose you have created right constraint.
//suppose initial value of right constraint is 20
constraintTextView1Right.constant = 20 + self.view.bounds.width;
self.view.layoutIfNeeded();//forcefully apply constraint with new values
After this, at some point in button click or in other event or after some delay, you can change value of constraintTextView1Right to 20,
constraintTextView1Right.constant = 20
self.view.layoutIfNeeded();//forcefully apply constraint with new values
your textFiled will come in the screen.
To animate the same you can write below code.
constraintTextView1Right.constant = 20
UIView.animateWithDuration(0.3) { () -> Void in
self.view.layoutIfNeeded();//forcefully apply constraint with new values
}

(swift) update a number to label will make the view get back to original position

demo image
When I update a number to label will make the view get back to original position.
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
#IBOutlet var aview: UIView!
var number = 0
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func plus(sender: UIButton) {
number++
label.text = "number:\(number)"
}
#IBAction func move(sender: AnyObject) {
aview.frame.origin.y -= 20
}
}
I couldn't find the answer on web, please help me to fix this problem.Thank you very much!
Because your xib or Storyboard you set use Autolayout:
So if you don't set constrain system will auto generate it. When you change frame by set frame it effect but when you access to it. It will auto back to old position.
if you don't want it happen. You set in viewDidLoad:
self.view.translatesAutoresizingMaskIntoConstraints = false
Issue is probably related to a constraint reloading when the label reloads.
Instead of setting aview.frame.origin.y -= 20 you should make an outlet to the constraint holding the y position of your aView and then update the constant of that constraint outlet instead.

Setting a Border for TextView (Xcode 6.1)

I've tried finding the answer to this and every time it's assuming I know way too much. I'm a total beginner. I just created a new, blank application. I dragged the TextView to the storyboard. What do I do next to give it a border?
There is no code other than the default, autogenerated code at this point.
Here are the steps:
If you let Xcode create a project, go to the ViewController.swift file. Here you can create an outlet.
#IBOutlet var text : UITextField?
Now you can connect the text outlet to the textfield in the storyboard. You can do this by choosing the assistant editor. Than control drag a line from the outlet in the code to the textfield.
After the textfield is connected, you can add code to make a border in the viewDidLoad function.
class ViewController: UIViewController {
#IBOutlet var text : UITextField?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
text!.layer.borderWidth = 1
text!.layer.borderColor = UIColor.redColor().CGColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In Swift 3 and Xcode 10,
tested and working in (swift 5 and code 12)
first, create an outlet of your text view
And In your viewdidload put these two lines
class ViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.textView.layer.borderColor = UIColor.lightGray.cgColor
self.textView.layer.borderWidth = 1
}
}