how to add element using swift to a storyboard stackview - ios

I am a beginner so sorry if it is a stupid question but I am trying to add new elements to a stack view that was made with a storyboard. I want to do it every time a button was pressed and I want the same color, size, constraint... how do I do this?
here is an image of my code
and this is the image of my storyboard structure
and this is what I made with the storyboard
and I want to add another button like the other ones every time the settings button is pressed
pls, can anyone help?

Connect your stack view to an #IBOutlet such as:
#IBOutlet var stackView: UIStackView!
Instead of trying to "copy" the button you designed in Storyboard, use a function to create a new button with your desired properties:
func makeNewButton() -> UIButton {
// create a button
let b = UIButton()
// set your desired font
b.titleLabel?.font = .systemFont(ofSize: 18.0, weight: .light)
// set background color to your desired light-green
b.backgroundColor = UIColor(red: 0.0, green: 0.85, blue: 0.0, alpha: 1.0)
// set title colors for normal and highlighted
b.setTitleColor(.white, for: .normal)
b.setTitleColor(.gray, for: .highlighted)
return b
}
Now, your function for tapping the "Settings" button could look like this:
#IBAction func settingsButtonPressed(_ sender: Any) {
// call func that returns a new button with your
// desired colors, font, etc
let newButton = makeNewButton()
// set the title (presumably you'll be getting a new title string from somewhere)
newButton.setTitle("New Button", for: [])
// give it an action
newButton.addTarget(self, action: #selector(self.btnTapped(_:)), for: .touchUpInside)
// add it to the stack view
stackView.addArrangedSubview(newButton)
}
Edit the above code assumed an existing function for handling the button action - such as:
#objc func btnTapped(_ sender: UIButton) {
// do something when the button is tapped
print("A button was tapped...")
}

Related

Fill button icon when button pressed in swift

I have a button with icon, I want when pressed button icon fill with color and when pressed again empty color and return to the previous state
Note: As much as possible I do not want to change icon after every pressed.
Here is example how you can achieve that, let me know if you don’t understand something.
class ViewController: UIViewController {
#IBOutlet weak var someBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
}
//Setting up images for normal and selected state.
func configureUI() {
let image = UIImage(named: "image")
let imageFilled = UIImage(named: "image-filled")
someBtn.setImage(image, for: .normal)
someBtn.setImage(imageFilled, for: .selected)
}
#IBAction func someBtnPressed(_ sender: Any) {
// Toggle basically makes someBtn’s selected state either true or false when pressed
someBtn.isSelected.toggle()
}
}
You can call setImage(_:for:) method to set the image of the button for a particular state.
The button is at the normal state when the user is not pressing it, so you should do:
yourButton.setImage(hollowHeart, for: .normal)
The button is at the highlighted state when the user is touching it, so you should do:
yourButton.setImage(filledHeart, for: .highlighted)
You just need to do this once after you create the button, probably in viewDidLoad.

Swift UIButton Tint Text When Highlighted

In my app, I have a button with a text title next to a button that's an image. I want the color scheme of both buttons to match. I create the button with the image like this:
let button1 = UIButton()
button1.setImage(
UIImage(named: "button1")?.withRenderingMode(.alwaysTemplate), for: .normal)
button1.tintColor = UIColor.green
This creates the effect that I want on both buttons, i.e. the button is green, then when it's highlighted it gets tinted to a darker, black-ish green. I tried creating the text button the same way:
let button2 = UIButton()
button2.setTitle("button2", for: .normal)
button2.tintColor = UIColor.green
But, in this case, setting the tint color doesn't change the color of the button's title/text (it remains white even when highlighted). My solution to this is as follows:
let button2 = UIButton()
button2.setTitle("button2", for: .normal)
button2.setTitleColor(UIColor.green, for: .normal)
button2.setTitleColor(UIColor(red: 0x23 / 255.0,
green: 0x34 / 255.0,
blue: 0x16 / 255.0,
alpha: 1.0), for: .highlighted)
Essentially, I've estimated the color that the image gets tinted to when it's highligted and set the text color to match. This works fine, but it bothers me that I only have an approximation; ideally, I would want the system to tint the text color for me when the button is highlighted in the same way that it tints the image. I get that this is a really small problem and that fixing it probably won't noticeably improve the app, but I'd still like to know if there's a way to tint a button with a text title "automatically" (as opposed to hardcoding the tint).
Tint color is property of UIView, which doesn't have a state. State is property of UIControl(Button's parent class). Means that you cannot change the tint on the bases of button's state. You can only change properties mentioned seen in this screen shot on the basis of button's state by default.
Also the
darker, black-ish green
color your getting that the default behaviour of button to change background color to show highlighted state
Solution : CustomButton
Create a custom UIButton
class MyButton : UIButton {
override var isHighlighted: Bool{
didSet {
tintColor = isHighlighted ? UIColor.green : UIColor.red
// do additional work here according to your need
}
}
override var isSelected: Bool {
didSet {
// do changes according to you need
}
}
}
You can also set the properties mentioned in above image programmatically.
button.setTitleColor(UIColor.green, for: .normal)
button.setTitleColor(UIColor.red, for: .highlighted)
button.setBackgroundImage(yourBackgroundImage, for: .normal)
let button2 = UIButton()
button2.addTarget(self, action: #selector(self.pressed), for: [.touchDown])
button2.addTarget(self, action: #selector(self.released), for: [.touchDragExit, .touchUpInside, .touchUpOutside, .touchCancel])
func pressed() {
// set colour
}
func released() {
// set colour
}

Access UIControls from Views outside the storyboard

My view (in the Main.storyboard) contains another UIView which takes only about 80% of the screen's height (set with constraints).
In this second view (I call it the viewContainer) I want to display different views, which works with
viewContainer.bringSubview(toFront: someView)
I created a new group in my project which contains 3 UIViewController classes and 3 xib files which I want to display in my viewContainer.
For each of those xib files I changed the background color to something unique so I can tell if it's working. And it does so far.
Now I tried adding a UIButton to the first UIViewController class and added an #IBAction for it. That just prints text to the console.
When I run the app I can switch between my 3 classes (3 different background colors) and I can also see and click the button I added to the first class when I select it.
But the code is never executed and my console is empty. Is that because my 3 other Views are not shown in my Main.storyboard?
SimpleVC1.swift
import UIKit
class SimpleVC1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func onButtonPressed(_ sender: Any) {
print("test")
}
}
Try using a target instead (and programmatically create the button), it might be easier:
import UIKit
class SimpleVC1: UIViewController {
var button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
button.frame.size = CGSize(width: 100, height: 100)
button.center = CGPoint(x: 100, y: 100)
button.setTitle("Control 1", for: .normal)
button.addTarget(self, action: #selector(control1), for: .touchUpInside)
button.backgroundColor = UIColor.blue
button.setTitleColor(UIColor.white, for: .normal)
}
#objc func control1() {
//Add your code for when the button is pressed here
button.backgroundColor = UIColor.red
}
}

how to change UI Button shape programmatically?

I have a button that contains a finger print image like the picture above. that fingerPrint button has a function to segue to viewController2. that fingerPrint button exists on the viewController1.
when the viewController1 is opened for the first time, I will get a data from the server, if I don't have that data, I shouldn't segue to viewController2 .
but sometimes we have an error as the response of my request. if I get the error response, then I want that finger button to be rectangular button that has 'Refresh' as the title and has different function to make request again to the server
how to achieve change the shape of existing UI Button?
class ViewController1 : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getDataFromServer()
}
#IBAction func fingerPrintButtonDidPressed(_ sender: Any) {
}
func getDataFromServer() {
// send request to get data from server
}
}
It is usually best to do it either all in code or all in storyboard. To do it in storyboard I suggest one of the following:
Create 2 buttons and in code hide one or another depending on your state
Assign different images and texts for different button states (there is a dropdown in interface builder) and then change the state of a button in runtime
To do it in code overall I suggest simply changing the values.
Assume you have something like this:
enum ViewState {
case idle
case success
case failed
}
var state: ViewState = .idle {
didSet {
refreshButton()
}
}
Now you can set your state when you get a response or on any event needed. All you need to implement is refreshButton.
func refreshButton() {
switch state {
case .idle:
button.setTitle(nil, for: .normal)
button.setImage(fingerprintImage, for: .normal)
button.backgroundColor = .clear
case .success:
button.setTitle(nil, for: .normal)
button.setImage(fingerprintImage, for: .normal)
button.backgroundColor = .clear
case .failed:
button.setTitle("REFRESH", for: .normal)
button.setImage(nil, for: .normal)
button.backgroundColor = .green
}
}
You can then use the same switch inside your button action (on press).
if isError
{
button.type = .system
button.backgroundColor - UIColor.green
button.setTitle("REFRESH" for: .normal)
button.addTarget(--------)
}
else
{
button.type = .custom
button.setImage(UIImage(named: "yourImageName.png") for: .normal)
button.addTarget(--------)
}
Simple Solution is : Use two buttons one for figure Image second for Refresh text. And use button isHidden property vice-versa.
For Auto layout
If you are using Auto layout then use constraint IBOutlet and change it's constant property value. it will change your button height or width.
For Auto resize
if you are using Auto resize than you can change you button frame which you want

Swift: Change colour of button when tapped

I'm new to Swift and I'm trying to change the button colour on tap. When the button is tapped, it should change colour and when released it should go back to the original button colour.
An example of this is the calculator. When you tap a button, it changes from light grey to dark grey and when the user removes their finger off the button, it goes back to the original light grey colour. How do I go about doing that?
So far, I've only got this..
#IBAction func changeButtonColourOnTouch(sender: UIButton) {
zeroButton.backgroundColor = UIColor.blueColor()
}
The above code changes the button colour to blue but stays blue.
The problem is, after releasing the button, you should return the color to the original state.
You can link direct from storyboard, in the action TouchUpInside (release) and TouchDown (press) , to change the button color to the correct state in each event.
Or you can add a Target in the button by code, linking to the functions, as the code bellow shows it.
zeroButton.addTarget(self, action: Selector("holdRelease:"), forControlEvents: UIControlEvents.TouchUpInside);
zeroButton.addTarget(self, action: Selector("HoldDown:"), forControlEvents: UIControlEvents.TouchDown)
//target functions
func HoldDown(sender:UIButton)
{
zeroButton.backgroundColor = UIColor.blueColor()
}
func holdRelease(sender:UIButton)
{
zeroButton.backgroundColor = UIColor.whiteColor()
}
Code adapted by the present in the link UIButton with hold down action and release action
The checked answer above works, but if the user holds down on the button, then drags out, the background color won't return to normal. It's a tiny UI bug, but a simple fix. This includes the code of the checked answer.
zeroButton.addTarget(self, action: #selector(holdRelease), for: .touchUpInside);
zeroButton.addTarget(self, action: #selector(heldDown), for: .touchDown)
zeroButton.addTarget(self, action: #selector(buttonHeldAndReleased), for: .touchDragExit)
//target functions
#objc func heldDown()
{
zeroButton.backgroundColor = .blue
}
#objc func holdRelease()
{
zeroButton.backgroundColor = .white
}
#objc func buttonHeldAndReleased(){
zeroButton.backgroundColor = .blue
}
you could also use a tap gesture and change the color of the button as the user is tapping on the button
you could see apple documentation regarding UIGestureRecognizer in here
it is a little bit advanced, but you will learn a lot from it.
You can also use setbackgroundImageForState to define color image as button background for all UIControlState you are interested in e.g. Normal, Highlighted, Disabled, Selected.
let cx = UIGraphicsGetCurrentContext()
let color = UIColor.redColor()
let state = UIControlState.Selected
UIGraphicsBeginImageContext(CGSize(width:1, height:1))
CGContextSetFillColorWithColor(cx, color.CGColor)
CGContextFillRect(cx, CGRect(x:0, y:0, width:1, height:1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.zeroButton.setBackgroundImage(colorImage, forState: state)
Now color changes automatically and you don't have to handle it manually.
If you want that for a programmatically defined button, just declare the button of type system during its initialisation:
let button = UIButton(type: .system)

Resources