I am building my first iOS-App using Swift and I am stuck.
I have a CollectionView and inside one of the Cells there is a button and an imageView.
What should happen is: I click the button and the imageView shows another picture.
I already created a CellSubClass but I just don't get how to use it.
Can anyone PLEASE help me?
Write an action method for your button inside your cellClass like this:
func changeImage
{
var image: UIImage = UIImage(named: "your image name")!
yourImageView.image = image
}
Don't forget to "assign" this method to your button either in initialization method for the cell (awakeFromNib is also called when cell is started or oyu could write your own custom init method). You can also do it by using IBAction from storyboard (Simple dragging and clicking).
But programmatically it is done Like this if you use the awakeFromNib approach:
override func awakeFromNib() {
super.awakeFromNib()
yourButton.addTarget(self, action: "changeImage", forControlEvents: UIControlEvents.TouchUpInside)
}
To learn how to create IBAction using storyboard, read here.
Related
I have a custom UITableViewCell subclass where I am putting two buttons in the cell, I want both to be clickable, but so far I cannot even get any kind of click to trigger (besides row selection, but I disabled that on my UITableViewController subclass). Basically When one of two buttons is selected, it should remove those two buttons and update what is in the cell with a list of selectable choices (also buttons). I am doing everything programmatically (no IB).
My TableViewCell with Initial Two Buttons
I have looked around a lot and haven't found anything that handles more than ONE button in a tableViewCell. Currently I've been trying to add targets to my buttons in my UITableViewCell's awakeFromNib():
for button in initialChoiceButtons{
button.isUserInteractionEnabled = true
button.addTarget(self, action: #selector(initialChoicePressed(sender:)), for: UIControlEvents.touchUpInside)
}
One thing I've tried is in my tableView in cellForRowAt for my custom cell is to bring my buttons to the front of the cell:
for button in (cell as! FormDropDownTableViewCell).initialChoiceButtons{
cell.bringSubview(toFront: button)
}
I'm really stumped and feel like this should easy. I'm on the verge of just using a stackView inside of scrollview for everything...
Ok so I figured out a somewhat clean way to separate button taps in my tableviewcell, by creating a delegate protocol with a function that I'll call from my target in my tableviewcontroller for every button in my tableviewcell.
protocol UIButtonSelectorDelegate{
func handleTap(button:DelegatingButton) //will select different functions based on DelegatingButton.actionType
}
class DelegatingButton:UIButton{
var selectorDelegate:UIButtonSelectorDelegate?
var actionType:String = "default"
}
in my FormDropDownTableViewCell I conform to the UIButtonSelectedDelegate and implement handleTap like so:
func handleTap(button:DelegatingButton){
switch button.actionType{
case "initialChoiceSelect":
initialChoicePressed(initialChoice:button) //specific method for certain button.actionType also in my FormDropDownTableViewCell
case "cardTypeSelect":
cardTypeSelected(selectedCardType:button)
default:
break
}
}
Now I add the target-actions for every button in cellForRowAt in my tableviewcontroller like so:
button.addTarget(self, action: #selector(handleButtonTaps), for: UIControlEvents.touchUpInside)
and the handleButtonTaps func in the tableviewcontroller is simple:
func handleButtonTaps(sender: DelegatingButton){
sender.selectorDelegate?.handleTap(button: sender)
}
Enjoyed Talking to myself =P ..
I'm trying to create a custom class that creates a button. I'm having trouble adding a target to that button inside it's class. This is my code
class SelectButton{
var button:UIButton = UIButton()
init(button_frame: CGRect, button_title: String, connected: [UIButton]?){
self.button.frame = button_frame
self.button.setTitle(button_title, for: UIControlState.normal)
self.button.addTarget(self, action:#selector(self.buttonPressed), for: .touchUpInside)
}
func construct() -> UIButton {
return self.button
}
#objc func buttonPressed() {
print("Button Clicked")
}
}
The problem is that I can't connect an action on button click. This works if it's used outside my class but not inside.
Usage of the class
let test = SelectButton(button_frame: CGRect(x:50, y:50, width: 250, height:150), button_title: "Test button", connected: nil).construct()
self.view.addSubview(test)
When someone taps the button, usually you want something to happen somewhere else in your app (like in one of your view controllers or in some other UI element). The way the IBAction is set up right now, you have it so that something will trigger or happen within the button itself when someone taps on it. If you want to handle a button tap programmatically instead of ctrl dragging from the button into the view controller, you can do it this way if you prefer. First, add this code into the view controller:
#IBAction func buttonPressed(sender: UIButton) {
}
Then you can either add the selector programmatically by adding this method into your view controller:
myButton.addTarget(self, action:self.buttonPressed(sender), for: .touchUpInside)
Or by going to the connections inspector and dragging from the touch up inside over to the IBAction dot in your view controller code. Also, as someone else pointed out in the comments you should make your button inherit from UIButton by adding this to your class declaration:
class SelectButton: UIButton {
. . .
}
Nothing is holding a strong reference to your SelectButton instance, so as soon as the function that creates test exits, that instance is released.
The button itself is retained because you have added it as a subview. Therefore, it is still visible but there is no longer an object to respond to the action.
You either need to use an instance property rather than a local variable for test, or, preferably have SelectButton inherit directly from UIButton
In my view controller's viewDidLoad, I added a button:
let tutorialButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton
tutorialButton.frame = CGRectMake(0, (UIScreen.mainScreen().bounds.size.height/4)*3, UIScreen.mainScreen().bounds.size.width, 20)
tutorialButton.titleLabel?.textAlignment = NSTextAlignment.Center
tutorialButton.backgroundColor = UIColor.clearColor()
tutorialButton.setTitle("View Quick Tutorial", forState: UIControlState.Normal)
tutorialButton.addTarget(self, action: "giveTutorial:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(tutorialButton)
The button appears where I want it and that part works great. But after it has served it's purpose and I no longer want it visible, how do I remove the button from the view? I've researched that it's usually done like this:
buttonName.removeFromSuperview
However, when I type in buttonName, it does not recognize the button. I guess because there's no IBOutlet. So then what code can I stick in a method that'll get this button removed?
Declare a class variable (not an IBOutlet) to hold the button reference.
var tutorialButton : UIButton?
Populate button in code and remove with
tutorialButton?.removeFromSuperview
My problem turned out to be not in what code I typed, but where I typed it. Because I wanted the view to be added upon load, I added the whole chunk of code to my viewDidLoad. However, this line did not belong there:
let tutorialButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton
By declaring tutorialButton within the viewDidLoad, I caused it to not be accessible/reference-able outside of the viewDidLoad. To fix this, all I had to do was move that line outside of the viewDidLoad.
let tutorialButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
...
This is a key thing to take note of if you plan to edit or remove the view later, from a method other than the viewDidLoad. Now that I made the change, I can add the removeFromSuperview call to a buttonPress and it works great:
tutorialButton?.removeFromSuperview
Normally you can link a slider to an #IBAction using the storyboard, then anytime the slider is moved, that method is executed, but...
Let's say I have a slider inside a tableViewCell. Normally I can only access it by tag because it isn't the same slider as the one on the StoryBoard:
let slider = cell.viewWithTag(1000) as UISlider
And change or access it like this:
slider.value = lroundf(50)
But what if I want to link it to an #IBAction? What if I want it to do something when the slider is moved? How would I do this if it's inside a cell?
I noticed that there's a method called "didChange", but there is absolutely no documentation anywhere on how to use this method or if it does what it is I'm trying to do.
slider.addTarget(self, action: "sliderMoved:", forControlEvents: .ValueChanged)
func sliderMoved(slider: UISlider) {
println("value: \(slider.value)")
}
I have two classes UIVIewController and UITableviewcell. In UITableviewcell, i have a button and the button action should be in UIViewController. How can i pass a class and set delegate in button action.
i tried this code,
//UIVIewController
cell.createButton(self)
func buttonClick(object:AnyObject){
println("Button Clicked")
}
//UITableViewCell
func createButton(delegate:AnyObject){
//button created.
button.addTarget(delegate, action: "buttonClick:", forControlEvents: UIControlEvents.TouchUpInside)
}
But the above code is not working. 'buttonClick' function is not calling
I had the same problem a while ago, trying to put self in place of "delegated".
otherwise try to take a look at this question:
link
I hope to be helped.