How can I trigger an action in Swift when two buttons are pressed simultaneously? My code below triggers the action when one button is pressed. I would like this action to trigger only if both buttons are tapped.
class ViewController: UIViewController {
#IBOutlet weak var leftButton: UIButton!
#IBOutlet weak var rightButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
leftButton.addTarget(self, action: #selector(ViewController.leftButtonClicked), forControlEvents: .TouchUpInside)
}
func leftButtonClicked() {
// Do something
}
}
Do I need to use UIGestureRecognizer or can this be done with the addTarget action above? How would the code look like?
With the help of the comment above I have now written the solution in Swift and it turns out to be very simple:
class ViewController: UIViewController {
#IBOutlet weak var leftButton: UIButton!
#IBOutlet weak var rightButton: UIButton!
#IBAction func touchButton(sender: AnyObject) {
if leftButton.touchInside && rightButton.touchInside {
print("Two buttons pressed")
}
I removed the clutter that is not relevant for the solution.
Related
everyone!
I am trying to add gesture to a UIImageView into the TableViewCell.
When click on the ImageView - the color changes.
class StocksCellView: UITableViewCell {
#IBOutlet weak var logoImageView: UIImageView!
#IBOutlet weak var tickerLabel: UILabel!
#IBOutlet weak var favouriteImageView: UIImageView!{ didSet {
let panGesture = UITapGestureRecognizer(target: self,
action: #selector(gestureAction))
favouriteImageView.addGestureRecognizer(panGesture)
}
}
#IBOutlet weak var companyNameLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var deltaLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
#objc func gestureAction() {
favouriteImageView.tintColor = UIColor.yellow
}
}
But nothing works.
If i change favouriteImageView.addGestureRecognizer(panGesture)
on addGestureRecognizer(panGesture)
Then, by clicking on the cell, the color will change.
But I want by clicking on the picture.
enter image description here
First of all you must check and change like below:
favouriteImageView.isUserInteractionEnabled = true
I have a custom class which inherits from UIView inside of which is a UIImageView and button. I'm adding them to my storyboard as UIView and let's say there are two views. I have a delegate and a function which executes when the button is pressed and it works for both UIViews.
My problem is that I don't know how to tell which one was clicked. I need to pass it to another VC and then display suitable image in the UIView which was clicked. I've been thinking of setting ids or something but it does not seem like a very scalable idea.
And I cannot simply add #IBAction because the view is UIView as a whole.
Inside the ViewController I've added them as #IBOutlets:
#IBOutlet weak var view: CustomImageView!
#IBOutlet weak var view2: CustomImageView!
EDIT:
I'm pretty close to creating reusable and scalable solution - I'm just assigning the tag to every object and than passing it and retrieving it. Problem I've encountered is that I would like to access properties of a tag. I didn't find any solution on how to do it.
Solution with delegates
You could add a custom delegate protocol for your custom view
protocol CustomViewDelegate {
func didSelectCustomView(_ view: CustomView)
}
class CustomView: UIView {
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var myButton: UIButton!
weak var delegate: CustomViewDelegate?
#IBAction func buttonPressed(sender: UIButton) {
delegate?.didSelectCustomView(self)
}
}
And in your ViewController you have to check from which view to delegate call comes:
class ViewController: UIViewController {
#IBOutlet weak var view1: CustomView!
#IBOutlet weak var view2: CustomView!
override func viewDidLoad() {
super.viewDidLoad()
view1.delegate = self;
view2.delegate = self;
}
}
extension ViewController: CustomViewDelegate {
func didSelectCustomView(_ view: CustomView) {
if view == view1 {
// view1 clicked
} else {
// view2 clicked
}
}
}
Solution with blocks
Instead of a delegate, you could add an optional block that is executed if the button in the view was clicked:
class CustomView: UIView {
#IBOutlet weak var myImageView: UIImageView!
#IBOutlet weak var myButton: UIButton!
var clicked: ((CustomView) -> Void)?
#IBAction func buttonPressed(sender: UIButton) {
clicked?(self)
}
}
And in your ViewController, you can add the block to your views:
class ViewController: UIViewController {
#IBOutlet weak var view1: CustomView!
#IBOutlet weak var view2: CustomView!
override func viewDidLoad() {
super.viewDidLoad()
view1.clicked = { view in
}
view2.clicked = { view in
}
}
}
I am trying to change the image of a button when clicked, they are stars like a rating system. when clicked the image remains the same and does not change when clicked. I set the default image in story board.
class DetailViewController: UIViewController {
#IBOutlet weak var detailTitleViewLbl: UILabel!
#IBOutlet weak var detailDescription: UILabel!
#IBOutlet weak var yearLabel: UILabel!
#IBOutlet weak var star1: UIButton!
#IBOutlet weak var star2: UIButton!
#IBOutlet weak var star3: UIButton!
#IBOutlet weak var star4: UIButton!
#IBOutlet weak var star5: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func star1Pressed() {
star1.setImage(#imageLiteral(resourceName: "favorite (1).png"), for: UIControlState.selected)
}
func star2Pressed() {}
func star3pressed() {}
func star4pressed() {}
}
A button doesn't change to the selected state when clicked. You need to write code that sets the button's selected flag to true when it's clicked.
Note that you can connect more than one IBAction to a button, so you could have one action that sets the selected flag to true, and another that does custom "stuff", so you don't have to duplicate the "boilerplate" code to set the selected state in the IBAction of every such button.
So I'm pretty new but I'm trying to reference a button from another. I disable the first button when I press it, but I want to enable it when I press the other button. Check this out. It doesn't like my second sender reference.
#IBAction func IBbtnUpdateTap(sender: UIButton){
sender.enabled = false
}
#IBAction func addSpinsButton() {
sender.enabled = true
}
Any ideas from you coding wizards?
The problem is that the context of your function addSpinsButton as no sender variable. You must add a reference to your button in the class.
You can do this with something like:
#IBOutlet weak var myButton: UIButton!
Link the button in interface builder (same way you have done with your function, but for the outlet)
Then your addSpinsButton will become:
#IBAction func addSpinsButton() {
myButton.enabled = true
}
what you need is something like this:
class ViewController: UIViewController {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBAction func button1Tapped(sender: UIButton) {
sender.enabled = false
}
#IBAction func button2Tapped(sender: UIButton) {
button1.enabled = true
}
}
I have more than one UISwitch on the same view. On my form, I need to use UISwitch like radio button (web). No more than one UISwitch can be on at he same time, I need just one.
If a UISwitch turning on, I want to check others and if there are any UISwitch with on mode, need to turn it off. Is it possible?
I can check it in a button action but, I want to change UISwitch status real time.
UPDATE AFTER SOLVED:
Here is my code:
#IBOutlet weak var firstSwitch: UISwitch!
#IBOutlet weak var secondSwitch: UISwitch!
#IBAction func firstSwitchAction(sender: AnyObject) {
if self.secondSwitch.on == true {
self.secondSwitch.setOn(false, animated: true)
}
}
#IBAction func secondSwitchAction(sender: AnyObject) {
if self.firstSwitch.on == true {
self.firstSwitch.setOn(false, animated: true)
}
}
You need to create outlets for your switches, you can change them with the .setOn method
A quick example
#IBOutlet weak var mySwitch: UISwitch!
#IBOutlet weak var myOtherSwitch: UISwitch!
#IBAction func mySwitchTouched(sender: UISwitch) {
if sender.on == true {
myOtherSwitch.setOn(false, animated: true)
}
}