Ios Swift programatically change view order over storyboard - ios

I have a textView and an imageView added in storyboard as shown in the screenshot below.
In story board order is:
textView
imageView
Now in run imageView covers textView and things assigned to textView does not work.
So I programmatically want to change the order to:
imageView
textView
(Without touching storyboard)
I tried:
self.view.bringSubviewToFront(textView)
self.view.sendSubviewToBack(imageView)
and
imageView.layer.zPosition = 1
textView.layer.zPosition = 2
None of these is working for me

I guess the problem is you might be using these codes in viewDidLoad method. Try using in viewDidAppear
Or another try is using performSelector
write this in viewDidLoad or viewWillAppear
self.performSelector(#selector(changeOrder), withObject: nil, afterDelay: 0.2)
and write your order changing in this function
func changeOrder() {
imageView.layer.zPosition = 1
textView.layer.zPosition = 2
}
Edit
I have made a sample. Have a look.
https://github.com/RajanMaheshwari/OrderingLayer
I have tried the code and its working fine
class ViewController: UIViewController {
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.performSelector(#selector(changeOrder), withObject: nil, afterDelay: 0.2)
}
func changeOrder() {
myImageView.layer.zPosition = 1
myTextField.layer.zPosition = 2
}
}
My Storyboard
My Final Outcome after running the code
Now imageView is on layer 1 and textField is on layer 2 position
If you comment out the performSelector line then the outcome will be
Here the imageView is on layer 2 position and textField is on layer 1 position.

Related

Setting the background of an UIButton programmatically not working

I'm just trying to simply set the background image of the button, but whatever I try it is doing nothing. I also put a UIImageView there to see if there's any issue with the image file, but the image view is set perfectly fine. Do I have to set something in the properties of the button?
Here the code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let imageToSet = UIImage(named: "3-1")
b1.setBackgroundImage(imageToSet, for: .normal)
imageView.image = imageToSet
}
#IBOutlet weak var b1: UIButton!
#IBOutlet weak var imageView: UIImageView!
}
These are my setting for the button:
In Xcode 13 ,UIButton has four type are Plain,Grain,Tinted,Filled .When you create a button in storyboard , button type automatically set with Plain that means new UIButton configurations is on (If you set one of them 4).So when you try to use old behaviours like
setBackgroundImage(..)
setImage(..)
This functions not gonna effect on this button. So If you want to use old behaviours you need to set style Plain to Default

Swift: how to finish a UIView draw animation before changing a label

I have a little problem regarding the timing of an animation.
The sequence should be:
Button is pressed
Animation is displayed
Label is changed
In reality the sequence is:
Button is pressed
Label is changed
Animation is displayed
Here is the code of the main VC:
import Foundation
import UIKit
class MainVC: UIViewController {
var counter: Int = 0
#IBOutlet weak var counterLabel: UILabel!
#IBOutlet weak var nextButton: UIButton!
#IBOutlet weak var animationView: AnimationView!
#IBAction func nextButtonPressed(_ sender: UIButton) {
counter += 1
animationView.progress = 1
//this view draws a progress bar and animates it from 0 to 100% via CABasicAnimation.
counterLabel.text = "\(counter)"
animationView.progress = 0
//the progress bar is reset
}
override func viewDidLoad() {
super.viewDidLoad()
nextButton.setTitle("Next")
counterLabel.text = "\(counter)"
}
}
I've experimented with the dispatch queue, but I just can't get it to work right. Any ideas on how to solve this?
You don't show enough of your code for us to be able to help you specifically.
In general, you would set some object to be the delegate of your CAAnimation, and implement the method func animationDidStop(_ anim: CAAnimation, finished flag: Bool).
In that method you'd then change the label text (assuming finished == true.)
I don't really like the delegate pattern for animations. If you have multiple animations it can be painful to handle custom completion code for each one. What I've done is use the fact that you can attach objects to CAAnimation objects, and attach a closure to the animation. I then set the view controller to be the delegate, and in the view controller's animationDidStop(), I look for a closure attached to the animation, and execute it if there is one.
Edit:
See this article for a discussion on using key-value coding to attach objects to CAAnimation and CALayer objects:
Core Animation Key-value coding extensions
It's old, and written using Objective-C, but the concepts are the same in Swift, and very useful. For a more general discussion on key-value coding, which is updated for Swift, see this article: https://developer.apple.com/documentation/objectivec/nsobject/nskeyvaluecoding
(The two functions you need to know in Swift are setValue(_:forKeyPath:) and value(forKey:).)

How can I make a UIImage View clickable to segue to another view controller

I'm new in programming and I'm stuck with this little problem. I created a table view with several items, that passes data to a label and an image view through a segue. It all works fine, but now I want to make the image clickable, in order to segue to another view controller to show this image expanded. How can I do that?
class ViewController: UIViewController {
#IBOutlet var titleLabel: UILabel!
#IBOutlet var descLabel: UILabel!
#IBOutlet var imageView: UIImageView!
var titleName: String?
var descName: String?
var imageName: String?
func configureView() {
if let poster = self.imageName {
if let imagePoster = self.imageView {
imagePoster.image = UIImage (named: poster)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
titleLabel.text = titleName
descLabel.text = descName
self.configureView()
}
The easiest thing to do is to use a UIButton instead of an image view. Set it's type to custom and install the image into the button in IB (Interface Builder).
That way you can trigger an IBAction just like any other button. It also highlights on a touch like you'd expect, triggers on touch up rather than touch down, etc.
If you don't want to use a button-with-image, you have to set userInteractionEnabled = YES on the image view and install a tap gesture recognizer on it. See the docs on UITapGestureRecognizer for more information.

iOS Custom .xib view button tap detect in view controller (Swift)

So I am using a custom View (.xib) which contains couple of objects: UIImage view & UIButton. The custom view in contained and used in View controller UIView , however I can't seem to figure out how to detect if the button(from .xib) is tapped and launch a function in the view controller. Any suggestions?
I can However add UITap gesture to the entire Viewcontroller UIView, however Thats not what i need.
#IBAction func calculateTapped(sender : AnyObject) {
//You can get action here
}
Step 1
Link Your all button to to xib cocoa class
class DialogHandler: UIView {
#IBOutlet weak var acceptBtn: UIButton!
#IBOutlet weak var closeBtn: UIButton!
}
step 2
Add Below code in viewDidLoad()
if let customView = Bundle.main.loadNibNamed("DialogDemo", owner: self, options: nil)?.first as? DialogHandler {
dialogView = customView
customView.acceptBtn.addTarget(self, action: #selector(ViewController.acceptBtnPressed(sender:)), for: .touchUpInside)
}
step 3
Create Function for Button that can handle your click event
#objc func acceptBtnPressed (sender:UIButton) { print("Button Pressed") }

Working UIButton animations in Swift

I've been trying to get this snippit of code to work but I can't seem to get my UIButton to animate through images.
#IBOutlet weak var screenButton: UIButton!;
func animation(){
var animationButton : UIButton!;
var imageList = [UIImage]();
var image1:UIImage = UIImage(named:"3fingers-o-l-animation1.png")!;
var image2:UIImage = UIImage(named:"4fingers-o-l-animation1.png")!;
animationButtonscreenButton = screenButton;
imageList = [image1, image2];
animationButton!.imageView!.animationImages = imageList;
animationButton!.imageView!.animationDuration = 1.0;
animationButton!.imageView!.startAnimating();
}
After writing this code I've dragged a line from screenButton to the button I want to animate through the image in the Storyboard.
What am I doing wrong?
What you need to do is to not re-initialize the UIButton in the function animation; so, comment out this line:
//var animationButton : UIButton!
Besides just having an IBOutlet, we need also an IBAction to your function animation. Do the same thing as you do for your button by control dragging a "line" to the block of function (check IBAction, not IBOutlet).
A little walk-through while you are still in storyboard:
What you have is only one button named: animationButton, which is an IBOutlet from your storyboard to your code by control-dragging a "line".
For your animation function:
Control-drag also from storyboard from the button a "line" to the block of the animation function.
Set up an initial image for you button in storyboard as will be mentioned shortly below.
In addition, we need to set up an initial image in storyboard; otherwise, the image property of the button is nil.
Please do so in storyboard by clicking on the right hand side "Attributes Inspector" and then set an image where it says "image". As test, I set that up as "1.jpg".
Thus, you code should look like the following:
#IBOutlet weak var animationButton: UIButton!
#IBAction func animation()
{
print("button touched")
//var animationButton : UIButton!
var imageList = [UIImage]()
var image1:UIImage = UIImage(named:"1.jpg")!
var image2:UIImage = UIImage(named:"2.jpg")!
//animationButtonscreenButton = screenButton;
imageList = [image1, image2];
animationButton!.imageView!.animationImages = imageList
animationButton!.imageView!.animationDuration = 1.0
animationButton!.imageView!.startAnimating()
}
Just ran a quick test; it gets touch event and the images animate on the button. Hope this helps.

Resources