add bottom line to UIButton - Swift - ios

I use the extension to UIButton and I added it to my UIButton but I still can't see the line.
I'm missing something, please help
extension:
https://gist.github.com/Isuru-Nanayakkara/496d5713e61125bddcf5
my code:
let settingsButton : UIButton = {
let button = UIButton()
button.setTitle("Settings", for: .normal)
button.setTitleColor(.white, for: .normal)
button.addBorder(side: .Bottom, color: .white, width: 100)
return button
}()
I want to get something like this:

Add a UIView that has [x] points height and same width as the button, and its y position is the same as the height of the button.
let frame = CGRect(x: 0, y: button.frame.size.height, width: button.frame.size.width, height: 2)
let borderBottom = UIView(frame: frame)
borderBottom.backgroundColor= UIColor.white
button.addSubview(borderBottom)

Related

Can I align a button's label with its layout margins?

One way to left-align a UIButton's title is to set the contentHorizontalAlignment to .left (or .leading). But this places the title flush with the left edge of the button with no margin. A common way to add some margin is to set the contentEdgeInstets.
But my button extends from once edge of the screen to the other, so I would like the left and right margins to honor the layoutMargins. These margins might change as the view is resized or the device is rotated.
Is there a way to set the button's insets to observe these margins? Or should I create a button from a custom view where I can use my own label and anchor it to the layoutMarginsGuide?
I guess you can manually set the margin of the button using titleEdgeInsets to match the inset of the Cancel Button.
Have a look at the following, the two buttons are exactly the same aside from the origin.y and the titleEdgeInsets:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
view.backgroundColor = .white
let button = UIButton(frame: CGRect(x: 40, y: 40, width: 200, height: 80))
button.setTitle("Some really long title", for: .normal)
button.backgroundColor = .red
button.setTitleColor(.black, for: .normal)
let button2 = UIButton(frame: CGRect(x: 40, y: 160, width: 200, height: 80))
button2.setTitle("Some really long title", for: .normal)
button2.backgroundColor = .red
button2.setTitleColor(.black, for: .normal)
button2.titleEdgeInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
view.addSubview(button)
view.addSubview(button2)
It gives the following result:
Hope this helps :)
A subclassed button may work for you...
class RespectSuperviewMarginButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
if let sv = superview {
contentEdgeInsets.left = sv.layoutMargins.left
}
}
}
My current best answer is: no, this is not possible without subclassing.
The subclass implementation I am currently using is simple enough:
class LayoutMarginRespectingButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
contentEdgeInsets = layoutMargins
}
}

button does not work after adding uiview in swift 4

let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
After making a button, I wanted to move it little bit to the right. So, i made UI View to move the button inside the view. But, then, after this, the button does not work anymore. Can anyone tell me the solution?
Your code is working fine but need to clarify some points.
Reason Your button not working is below 4 lines
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
As you already set UIButton frame then no need to use of above lines of code.
Yellow color view is your SearchView and green color is your UIButton.
If you use Searchbutton frame like Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30) then it happens something like below image.
You added UIButton as subview of UIView and when you click on green button which is inside yellow View will work but the area which is outside Yellow area doesn't work.
You need to start UIButton frame from 0,0,30,30
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
or you can directly set UIButton frame same as UIView frame then it looks like below image.
Searchbutton.frame = SearchView.frame
Below is your Working Code.
let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
You're doing a lot of unnecessary things here. Firstly, you don't need to put your Button in a container view to put it as the right bar button item.
You also don't need to add constraints to your searchbutton, since you have given it a fixed frame.
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: Searchbutton)
self.navigationItem.rightBarButtonItem = barButtonItem
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
Also as Pratik's comment said, you're meant to use lower camel case. so SearchView should be searchView and SearchButton as searchButton
As for moving it to the right, it seems like that isn't possible anymore without either subclassing the UINavigationBar and changing the implementation, or by making UIViews look exactly like the standard Navigation Bar.
Get rid of the space on the right side of a UINavigationBar

Swift: Radio button into StackView are not displayed properly

I created a list of radio button in a stackView, but I do not understand why they are displayed wrong, they are not properly aligned
I want all my buttons to be correctly aligned on the left as I can solve this problem thank you!
Here is a part of the code:
var buttons = [UIButton]()
var titles = ["Lasy", "What I've been told", "I'm do into it", "Close the best i can", "Hard core"]
func setupUI() {
for title in titles {
// create button
let button = UIButton(type: .custom)
button.setTitleColor(.black, for: .normal)
button.setTitle(title, for: .normal)
button.setImage(UIImage(named: "uncheck.png")!, for: .normal)
// if the selected button cannot be reclick again, you can use .Disabled state
button.setImage(UIImage(named: "check.png")!, for: .selected)
button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35)
button.addTarget(self, action: #selector(radioButtonAction), for: .touchUpInside)
buttons.append(button)
}
for button in buttons {
addArrangedSubview(button)
}
setupUserChoice()
}
func setupUserChoice(){
if titles.contains(value) {
let valueIndex = titles.index(of: value)
radioButtonAction(sender: buttons[valueIndex!])
}
}
func setStackView() {
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 16.0
stackView.alignment = .leading
}
The problem is with the way you are trying to set the imageEdgeInsets. It is only adjusting the image position, not increasing the size of the button accordingly. For increasing the size of the button, you need to set contentEdgeInsets. But you also need to adjust the title position according to the change in image's position. You can use titleEdgeInsets for that.
So remove you code button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 35) and replace it with :-
let leftPadding_beforeImage: CGFloat = 35
let gapBetweenImageAndTitle: CGFloat = 8
let rightPadding_afterTitle: CGFloat = 16
button.imageEdgeInsets = UIEdgeInsetsMake(0, leftPadding_beforeImage, 0, 0)
button.titleEdgeInsets = UIEdgeInsetsMake(0, (leftPadding_beforeImage+gapBetweenImageAndTitle), 0, -(leftPadding_beforeImage+gapBetweenImageAndTitle))
button.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, (leftPadding_beforeImage+gapBetweenImageAndTitle+rightPadding_afterTitle))
I hope the variable names are self-explanatory. If you want to know more about UIButton edgeInsets, I suggest you reading this fantastic answer.
Set the frame of each button, because UIStackViews use intrinsic content size. for example :
button.frame = CGRect(x: 0, y: 0, width: 100, height: 20)

Button not shown swift

I am new to swift coding, when I am trying to add a button by code, it does not show up in the Simulator.
I changed the dimension of the View in main.storyboard to 375*1114
there are scroll view and view inside with the same dimension as well.
there are also 5 collection views too.
These are all setup by the storyboard.
The code I used:
let fullScreenSize = UIScreen.main.bounds.size
let plusButton = UIButton(type: .custom)
plusButton.frame = CGRect(x: 300, y: 600, width: 50, height: 50)
plusButton.layer.cornerRadius = 0.5 * plusButton.bounds.size.width
plusButton.clipsToBounds = true
plusButton.setImage(UIImage(named: "plus.png"), for: .normal)
plusButton.center = CGPoint(x: fullScreenSize.width * 0.9, y: fullScreenSize.height * 0.9)
plusButton.addTarget(self, action: #selector(plusButtonPressed), for: .touchUpInside)
self.view.addSubview(plusButton)
I was trying to let the button to stay at the right bottom corner of the simulator all the time. How can I do that? Thanks.
your code is fine and correct add the background color and check once the button will be visibile else check your plusButton.setImage(UIImage(named: "plus.png"), for: .normal) plus.png is correct or not
plusButton.backgroundColor = UIColor.red
for full code
let fullScreenSize = UIScreen.main.bounds.size
let plusButton = UIButton(type: .custom)
plusButton.frame = CGRect(x: 300, y: 600, width: 50, height: 50)
plusButton.layer.cornerRadius = 0.5 * plusButton.bounds.size.width
plusButton.clipsToBounds = true
plusButton.setImage(UIImage(named: "normal.jpg"), for: .normal)
plusButton.backgroundColor = UIColor.red
plusButton.center = CGPoint(x: fullScreenSize.width * 0.9, y: fullScreenSize.height * 0.9)
// plusButton.addTarget(self, action: #selector(plusButtonPressed), for: .touchUpInside)
self.view.addSubview(plusButton)
output
I think you have to take an Outlet of UIView inside UIScrollview you already have in you UIViewController and add that button as a subView of that UIView. That's why your button is hiding, why don't you check it by looking at the View Hierarchy!

UIButton label not showing

I have the following code
let width = UIScreen.mainScreen().bounds.width
let linkLabel = UILabel(frame: CGRect(x: 8, y: contentHeight, width: 100, height: labelHeight))
let linkButton = UIButton(frame: CGRect(x: 108, y: contentHeight, width: width - 108, height: labelHeight))
mainScrollView.addSubview(linkLabel)
mainScrollView.addSubview(linkButton)
linkLabel.text = "Link:"
linkButton.addTarget(self, action: #selector(linkButtonPressed), forControlEvents: .TouchUpInside)
linkButton.setTitle("http://example.com", forState: .Normal)
linkButton.layer.borderWidth = 1.0
mainScrollView.contentSize = CGSize(width: view.frame.width, height: contentHeight)
And when view loads i see the following picture (Note that button is black rectangle):
So title is not visible but when i click on the button i can fetch its title property
func linkButtonPressed(sender: UIButton) {
print("button title = \(sender.titleLabel?.text)")
}
And i get the button title = Optional("http://example.com") but anyway button title is not visible. Any suggestions?
Your button title is display but in white color.Give any color to button title it is there.There is no problem in your code.
linkButton.setTitle("http://example.com", forState: .Normal)
linkButton.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
You skipped one step. You should add title color :-
linkButton.setTitleColor(UIColor.blackColor(), forState: .Normal)

Resources