swift - UIBarButtonItem UIButton view alpha not working - swift

I'm creating a uibutton in an extension with the following code:
extension UIButton {
func customButton(_ title: String, selector: Selector) -> UIButton{
let button = UIButton()
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.black.cgColor
button.titleLabel!.font = UIFont.systemFont(ofSize: 16)
button.setTitle(title, for: UIControlState())
button.setTitleColor(UIColor.black, for: UIControlState())
button.setTitleColor(UIColor(r: 220, g: 220, b:220), for: .highlighted)
button.titleEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8)
button.layer.cornerRadius = 5
button.sizeToFit()
button.addTarget(self, action: selector, for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 80, height: 30)
button.alpha = 0.4
return button
}
}
The problem is that I'm using this button as a custom view in a UIBarButtonItem:
UIBarButtonItem(customView: self.customButton!)
That button is settingt he alpha to 0.4 but the button still shows up with full alpha!
I even tried switching it in the class after calling the customButton method and it simply does not work.
I'm trying to make the button seem disabled on first open and it's impossible to get that alpha to work.

Not sure why this is happening but I added this and we're good now.
override func viewWillAppear(_ animated: Bool) {
button?.alpha = 0.4
}
For some reason putting it in the viewWillAppear makes it so that the alpha is 0.4 on load.

Related

Implementing the same function for different objects

Newbie coder and learning Swift. I want the function to be applicable for both UIButtons and couldn't figure out how to make it happen for second one.
private lazy var boostButton: UIButton = {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 10, y: 10, width: 80, height: 80)
button.setImage(UIImage(named: "simsek.png"), for: .normal)
button.imageView?.contentMode = .scaleAspectFit
button.contentHorizontalAlignment = .center
button.contentVerticalAlignment = .center
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.layer.masksToBounds = true
button.addTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragEnter])
button.addTarget(self, action: #selector(touchUp), for: [.touchUpInside, .touchDragExit, .touchCancel])
return button
}()
private lazy var informationButton: UIButton = {
let button = UIButton(type: .custom)
button.frame = CGRect(x: 120, y: 10, width: 35, height: 35)
button.setImage(UIImage(named: "yenigozlukgri.png"), for: .normal)
button.imageView?.contentMode = .scaleAspectFit
button.contentHorizontalAlignment = .center
button.contentVerticalAlignment = .center
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.layer.masksToBounds = true
button.addTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragEnter])
button.addTarget(self, action: #selector(touchUp), for: [.touchUpInside, .touchDragExit, .touchCancel])
return button
}()
These are my buttons. I don't use storyboard but I believe that's not essential for the solution.
#objc func touchDown() {
animator.stopAnimation(true)
boostButton.backgroundColor = .red
//highlightedColor
}
#objc func touchUp() {
animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeOut, animations: {
self.boostButton.backgroundColor = .gray
})
animator.startAnimation()
}
What I want to do is, when one of the buttons are clicked, it should perform the animation. If I add informationButton like the boostButton to my functions, both of them perform the animation even though one button is clicked. It should work for just the clicked one. How can I fix it to be functional for even more buttons ?
Use the parameter
#objc func touchDown(_ sender:UIButton) {
animator.stopAnimation(true)
sender.backgroundColor = .red
//highlightedColor
}
#objc func touchUp(_ sender:UIButton) {
animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeOut, animations: {
sender.backgroundColor = .gray
})
animator.startAnimation()
}

How to have a button call a method programmatically in a class in swift?

I want the button to slide off the screen when it's hit, but that part of the code (buttonPressed) isn't working. When the method buttonPressed is inside the class, nothing happens when the button is pressed. Move the method outside of the brackets (to right before viewDidLoad) and the code executes. However, then it slides the entire view as opposed to just the tutorial window. I either need to find a way to make buttonPressed work as a method of the Tutorial class, or find a way to make it refer to the specific instance of "view" that's called in the class.
I'm new to coding and very new to methods, so any help is appreciated!
class Tutorial{
var label = UILabel()
var view = UIView()
var button = UIButton()
init (text: String){
view = UIView()
label = UILabel(frame: CGRect(x: 10, y: 10, width: 180, height: 90))
button = UIButton(frame: CGRect(x: 50, y: 110, width: 100, height: 30))
view.backgroundColor = .white
view.layer.cornerRadius = 15
view.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.text = text
label.numberOfLines = 10
label.backgroundColor = .white
label.textColor = UIColor(red:0.12, green:0.15, blue:0.23, alpha:1.0)
button.backgroundColor = UIColor(red:0.23, green:0.72, blue:0.44, alpha:1.0)
button.setTitleColor(.white, for: .normal)
button.setTitle("Got it!", for: .normal)
button.layer.cornerRadius = 15
view.addSubview(label)
view.addSubview(button)
button.addTarget(self, action: #selector(buttonPressed), for: UIControlEvents.touchUpInside)
}
func setConstraints(height: CGFloat){
view.centerXAnchor.constraint(equalTo: view.superview!.centerXAnchor).isActive = true
view.topAnchor.constraint(equalTo: view.superview!.topAnchor, constant: UIScreen.main.bounds.height-300).isActive = true
view.widthAnchor.constraint(equalToConstant: 200).isActive = true
view.heightAnchor.constraint(equalToConstant: height).isActive = true
UIView.animate(withDuration: 0.5, delay: 0.2, options: [], animations: {
self.view.center.x -= UIScreen.main.bounds.width
})
}
#objc func buttonPressed(){
print("Pressed")
UIView.animate(withDuration: 0.5, delay: 0.0, options: [], animations: {
self.view.center.x -= UIScreen.main.bounds.width
},
completion: { (finished: Bool) in
self.view.isHidden = true
})
}
}
override func viewDidLoad() {
super.viewDidLoad()
let tutorial1 = Tutorial(text: "Click and hold to see the anatomy overlay")
self.view.addSubview(tutorial1.view)
tutorial1.setConstraints(height: 150)
Try using Interface Builder Constants. Here is the Apple Documentation. https://developer.apple.com/documentation/appkit/constants/interface_builder_constants?language=objc
make an IBOutlet and an IBAction for your button.

tvOS Button Action

I create a UIButton in tvOS via Swift
let randomBtn = UIButton()
randomBtn.setTitle("Zufällig", forState: .Normal)
let RndNormal = UIImage(named: "RndNormal")
let RndHoover = UIImage(named: "RndHoover")
randomBtn.setImage(RndNormal, forState: .Normal)
randomBtn.setImage(RndHoover, forState: .Focused)
randomBtn.setTitleColor(UIColor.blackColor(), forState: .Normal)
randomBtn.setTitleColor(UIColor.whiteColor(), forState: .Focused)
randomBtn.addTarget(self, action: #selector(ViewController.click(_:)), forControlEvents: UIControlEvents.TouchUpInside)
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
randomBtn.frame = CGRect(x: screenWidth - 150, y: 60 , width: 70 , height: 70)
self.view.addSubview(randomBtn)
But the action never get fired if I press the button, is there anything different in tvOS?
func click(sender: UIButton) {
print("click")
}
In tvOS for Button action UIControlEvents TouchUpInside will not call.
You have to use UIControlEvents PrimaryActionTriggered like below.
randomBtn.addTarget(self, action: #selector(ViewController.click(_:)), forControlEvents: UIControlEvents. PrimaryActionTriggered)
Also Refer this link if you have any confusion
https://forums.developer.apple.com/thread/17925
randomBtn.addTarget(self, action: #selector(ViewController.click(_:)), forControlEvents: UIControlEvents.PrimaryActionTriggered)
Solved it, its just a other UIControlEvents

How to create a UIButton programmatically

I am trying to build UIViews programmatically. How do I get a UIButton with an action function in Swift?
The following code does not get any action:
let btn: UIButton = UIButton(frame: CGRectMake(100, 400, 100, 50))
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("Click Me", forState: UIControlState.Normal)
btn.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(buttonPuzzle)
The following selector function is:
func buttonAction(sender: UIButton!) {
var btnsendtag: UIButton = sender
}
You're just missing which UIButton this is. To compensate for this, change its tag property.
Here is you answer:
let btn: UIButton = UIButton(frame: CGRectMake(100, 400, 100, 50))
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("Click Me", forState: UIControlState.Normal)
btn.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
btn.tag = 1 // change tag property
self.view.addSubview(btn) // add to view as subview
Swift 3.0
let btn: UIButton = UIButton(frame: CGRect(x: 100, y: 400, width: 100, height: 50))
btn.backgroundColor = UIColor.green
btn.setTitle(title: "Click Me", for: .normal)
btn.addTarget(self, action: #selector(buttonAction), forControlEvents: .touchUpInside)
btn.tag = 1
self.view.addSubview(btn)
Here is an example selector function:
func buttonAction(sender: UIButton!) {
var btnsendtag: UIButton = sender
if btnsendtag.tag == 1 {
//do anything here
}
}
Using a tag is a fragile solution. You have a view and you are creating and adding the button to that view, you just need to keep a reference to it: For example
In your class, keep a reference to the button
var customButton: UIButton!
Create the button and set the reference
let btn = UIButton(frame: CGRect(x: 100, y: 400, width: 100, height: 50))
btn.backgroundColor = .greenColor()
btn.setTitle("Click Me", forState: .Normal)
btn.addTarget(self, action: #selector(MyClass.buttonAction), forControlEvents: .TouchUpInside)
self.view.addSubview(btn)
customButton = btn
Test against this instance in the action function
func buttonAction(sender: UIButton!) {
guard sender == customButton else { return }
// Do anything you actually want to do here
}
You have to addSubview and tag on that btn.

How to scale image and center it on a UIButton in Swift?

var button = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
var image = UIImage(named: "myimage.png") as UIImage!
button.frame = CGRectMake(0, 0, 100, 100)
button.setImage(image, forState: .Normal)
I have an image that I've set on my button, but I'd like to scale it to be smaller than the button (for example the image should be 50,50) and center in the button. How might I do this in Swift?
Xcode 8.3.1 • Swift 3.1
let button = UIButton(type: .custom)
let image = UIImage(named: "myimage.png")
func buttonTouchDown(_ button: UIButton) {
print("button Touch Down")
}
override func viewDidLoad() {
super.viewDidLoad()
button.frame = CGRect(x: 0, y: 0 , width: 100, height: 100)
button.backgroundColor = .clear
button.addTarget(self, action: #selector(buttonTouchDown), for: .touchDown)
button.setTitle("Title", for: .normal)
button.setTitleColor(.black, for: .normal)
button.setImage(image, for: .normal)
button.imageEdgeInsets = UIEdgeInsetsMake(25,25,25,25)
view.addSubview(button)
}
Swift 5, Swift 4, Swift 3
var image = UIImage(named: "myimage") as UIImage!
btnetc.setImage(image, for: .normal)
btnetc.imageView?.contentMode = .scaleAspectFill
or
btnetc.imageView?.contentMode = .scaleAspectFit
or
btnetc.imageView?.contentMode = .scaleToFill
Ther is a much easier way to do this where you don't have to deal with content insets. Here its is:
var button = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
var image = UIImage(named: "myimage.png") as UIImage!
button.frame = CGRectMake(0, 0, 100, 100)
button.setImage(image, forState: .Normal)
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
Or via XIB after selecting your UIButton.
Just make sure your insets are all the same.
Xcode 13, Swift 5
Using storyboard, select the button, then in the size inspect click the dropdown on size just above Content inset. There is a list of sizes to select from, and this will adjust your image size(if you use system image). The default size is already set when you added the button on the storyboard to the View Controller.