I created a UIBarButtonItem programmatically and the text is underlined. Is there a way to remove the underline?
let editButton = UIButton.init(type: .Custom)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.title = "General Information"
editButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
editButton.addTarget(self, action: #selector(editButtonPressed(_:)), forControlEvents: .TouchUpInside)
editButton.frame.size = CGSize(width: 60, height: 30)
editButton.titleLabel?.adjustsFontSizeToFitWidth = true
let barButtonItem = UIBarButtonItem.init(customView: editButton)
self.tabBarController?.navigationItem.setRightBarButtonItem(barButtonItem, animated: true)
updateEditButtonTitle()
self.navigationController!.navigationItem.backBarButtonItem?.tintColor = UIColor.blackColor()
}
here is an image of the result I get, with the underline.
here is the function where I set the button's text. when it is pressed, it becomes a save button.
func updateEditButtonTitle() {
if let button = self.tabBarController?.navigationItem.rightBarButtonItem?.customView as? UIButton {
var title = ""
editButton.backgroundColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.55)
editButton.layer.cornerRadius = 7.0
if isInEditMode {
title = "Save"
editButton.setTitleColor(UIColor.redColor(), forState: .Normal)
editButton.backgroundColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.5)
editButton.layer.cornerRadius = 7.0
editButton.frame.size = CGSize(width: 60, height: 30)
} else {
editButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
title = "Edit"
}
button.setTitle(title, forState: .Normal)
}
}
Try this code ..
var attrStr: NSMutableAttributedString = yourBtnHere.attributedTitleForState(.Normal).mutableCopy()
//or whatever the state you want
attrStr.enumerateAttributesInRange(NSMakeRange(0, attrStr.characters.count), options: .LongestEffectiveRangeNotRequired, usingBlock: {(attributes: [NSObject : AnyObject], range: NSRange, stop: Bool) -> Void in
var mutableAttributes: [NSObject : AnyObject] = [NSObject : AnyObject](dictionary: attributes)
mutableAttributes.removeObjectForKey(.AttributeName)
attrStr.setAttributes(mutableAttributes, range: range)
})
With the inspector/IB: Select your UIButton.
Show the Attributes Inspector.
The Text settings should be in Attributed. Select the text, click on the fond item remove the Underlining setting it at none.
enter image description here
But..
Let me get this straight. Apple added an accessibility feature that lets users mark buttons with underlines if they want to.
You want a way to defeat this feature, specifically designed to help people with handicaps use their devices, when the feature is something that the user has to ask for.
Why?
It is very likely not possible using standard buttons. If you did figure out a way to do it, Apple would likely reject your app because it defeats a system function meant to help the disabled.
So the answer is: Don't do that.
Related
I have a toolbar that is placed at the bottom (correctly). The problem is the button (on a UIBarButtonItem) sits in the center of the entire toolbar.
How can I position this button to the side, but still (vertically) centered with the image?
It'd be best with a margin.
So it'd look like
--------------
|. X
|. label
--------------
The code is:
let customButton: UIButton = UIButton(type: .custom)
customButton.setImage(UIImage(named: "start"), for: .normal)
customButton.setTitle("Start", for: .normal)
customButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 12)
customButton.setTitleColor(UIColor.white, for: .normal)
customButton.sizeToFit()
customButton.centerLabelVerticallyWithPadding(spacing: 5)
customButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(startButtonAction(_:))))
iconBar.items = [UIBarButtonItem(customView: customButton)]
Where iconBar - the toolbar is defined as:
let iconBar: UIToolbar =
{
let view = UIToolbar()
view.translatesAutoresizingMaskIntoConstraints = false
view.barTintColor = UIColor.black
return view
}()
Also I'm using an extension to center the UIButton, then I can add an image (also centered) above it. Here's the extension:
extension UIButton
{
func centerLabelVerticallyWithPadding(spacing:CGFloat)
{
// update positioning of image and title
let imageSize = self.imageView!.frame.size
self.titleEdgeInsets = UIEdgeInsets(top:0,
left:-imageSize.width,
bottom:-(imageSize.height + spacing),
right:0)
let titleSize = self.titleLabel!.frame.size
self.imageEdgeInsets = UIEdgeInsets(top:-(titleSize.height + spacing),
left:0,
bottom: 0,
right:-titleSize.width)
// reset contentInset, so intrinsicContentSize() is still accurate
let trueContentSize = self.titleLabel!.frame.union(self.imageView!.frame).size
let oldContentSize = self.intrinsicContentSize
let heightDelta = trueContentSize.height - oldContentSize.height
let widthDelta = trueContentSize.width - oldContentSize.width
self.contentEdgeInsets = UIEdgeInsets(top:heightDelta/2.0,
left:widthDelta/2.0,
bottom:heightDelta/2.0,
right:widthDelta/2.0)
}
}
Are you looking for the 'flexible space bar button item' or 'fixed space bar button item'? then you can add a little bit of space to the left and right inside the toolbar and define it's size.
It will look something like this:
let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
spacer.width = 10
I have UIButton, which title is dynamic changes. Button size should changes with title size and will be equal title size.
How to do this programmatically in Swift?
To have your button use its intrinsic content size and automatically resize based upon its text, use Auto Layout to position the button. Only set constraints to position the button and iOS will use the size of the text to determine the width and height of the button.
For example:
let button = UIButton()
// tell it to NOT use the frame
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Hello", for: .normal)
view.addSubview(button)
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
This also works if you create the button in the Storyboard. Again, only give constraints to place the button and it will resize to accommodate the text.
Follow below steps(its not a proper solution but you can solve your problem by doing like this )
Create a UILabel (because UILabel adjust its height and width depends on the text)
UIlabel number of line to 1
Create a UIButton over UILabel
Set button title to ""
Set button's constraint : Align button's top and leading to UILabel and equals width and height
Hope this will works for you :)
You can get UIButton's width and Height dynamically with its title.
With the help of, NSString's Size property we can achieve this.
let buttonNAme = [" hi ", "welcome", "Login", "Forgot Password ??", "New to here. Sign up??"]
var yPos = CGFloat()
override func viewWillAppear(_ animated: Bool) {
yPos = 40
for i in 0..<buttonNAme.count
{
self.view.addSubview(addingCustomButton(buttonTitle: buttonNAme[i], buttonFontSize: 15, buttonCount: i))
}
}
func addingCustomButton(buttonTitle : String, buttonFontSize: CGFloat, buttonCount : Int) -> UIButton
{
let ownButton = UIButton()
ownButton.setTitle(buttonTitle, for: UIControlState.normal)
ownButton.titleLabel?.font = UIFont.systemFont(ofSize: buttonFontSize)
let buttonTitleSize = (buttonTitle as NSString).size(attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: buttonFontSize + 1)])
ownButton.frame.size.height = buttonTitleSize.height * 2
ownButton.frame.size.width = buttonTitleSize.width
ownButton.frame.origin.x = 30
yPos = yPos + (ownButton.frame.size.height) + 10
ownButton.frame.origin.y = yPos
ownButton.tintColor = UIColor.white
ownButton.backgroundColor = .brown
ownButton.tag = buttonCount
ownButton.setTitleColor(UIColor.darkGray, for: UIControlState.highlighted)
ownButton.addTarget(self, action: #selector(ownButtonAction), for: UIControlEvents.touchUpInside)
return ownButton
}
func ownButtonAction(sender: UIButton)
{
print("\n\n Title \(sender.titleLabel?.text) TagNum \(sender.tag)")
}
Output
Just Constraint it's origin, and the size will fit it's button title
I'm trying to keep a button selected while its audio is being played. the problem is the button won't change unless I change it in a loop (while(audioPlayer.playing){button.selcted=true}). In this case I can't use the app until audio has finished(for obvious reasons)
hopefully someone can help me
func addButton(number: String, x:CGFloat, y:CGFloat){
let button = UIButton(type: UIButtonType.Custom) as UIButton
button.setTitle(number, forState: .Normal)
button.frame = CGRectMake(x, y, 68, 212)
if let image = UIImage(named: number) {
button.setImage(image, forState: .Normal)
}
button.addTarget(self, action: "play:", forControlEvents:.TouchUpInside)
self.view.addSubview(button)
}
#IBAction func play(sender: UIButton) {
button=sender
button.selected = true
let audioFilePath = NSBundle.mainBundle().pathForResource(sender.currentTitle, ofType: "WAV")
if audioFilePath != nil {
let audioFileUrl = NSURL.fileURLWithPath(audioFilePath!)
do { audioPlayer = try AVAudioPlayer(contentsOfURL: audioFileUrl, fileTypeHint: nil)} catch _ { return }
audioPlayer?.delegate = self
audioPlayer.play()
} else {
print("audio file is not found")
}
}
I just wrote up a test app to see what you are actually trying to do here, set sender.enabled = false is what you are looking for. (The button as an animation that goes to the faded out gray that is set by not enabled, then goes back to the original color of enabled, setting it to false prevents the second part from happening)
Edit: In the end, the results that were desired was an accessible button with the gray text, so we changed the text highlight state to a gray using sender.setTitleColor(UIColor.grayColor(),forState:.Highlighted) and the user will set the highlighted variable to true in the Play function.
I am trying to set a button image programmatically, and no one seems to have problems with this but me.
My Code:
func moreOptionsKeyMap(){
for x in self.mainView.subviews as [UIButton]
{
let image = UIImage(named: "\(numberImages[0])") as UIImage
if x.tag == 0 {
x.setImage(UIImage (named: image), forState: .Normal)
}
}
}
I tried directly plugging in the name of the image (This is the line throwing the error)
x.setImage(UIImage (named: "1Key.png"), forState: .Normal)
but I keep getting the same error.
I found an answer on Stackoverflow that said the solution is:
let image = UIImage(named: "name") as UIImage
let button = UIButton.buttonWithType(UIButtonType.System) as UIButton
button.setImage(image, forState: .Normal)
and everyone says that works fine, so I can't imagine what is wrong with mine.
I'm making a keyboard, so I have buttons set up in Interface Builder, and then in my viewDidLoad
for v in self.mainView.subviews as [UIButton]
{
v.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
}
then in the buttonPressed method I have a switch that calls moreOptionsKeyMap()
At a first glance I would say that here:
x.setImage(UIImage (named: image), forState: .Normal)
you are passing image, which is a UIImage, whereas a string is expected.
I think you have to turn this line:
let image = UIImage(named: "\(numberImages[0])") as UIImage
into:
let image = "\(numberImages[0])"
So this is how your method should look like:
func moreOptionsKeyMap() {
for x in self.mainView.subviews as [UIButton]
{
let image = "\(numberImages[0])"
if x.tag == 0 {
x.setImage(UIImage (named: image), forState: .Normal)
}
}
}
I wonder how you can add buttons (left and right) to change page controll views.
I'm working on this tutorial [1]: http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/ . How can I add 2 simple buttons (left and right) to turn pages in addition to the swaping function in this example code?
I'm a programmer beginner so any kind of answer is highly appriciated! :)
thanks!
You can add two buttons to the view and when the button is clicked call a method to turn the page according to the button clicked.
UIButton *leftButton = [[UIButton alloc] init];
leftbutton.frame = leftButtonFrame;
[leftbutton setTitle:#"Left" forState:UIControlStateNormal];
[leftbutton addTarget:self action:#selector(leftbuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[yourView addSubview:leftbutton];
UIButton *rightButton = [[UIButton alloc] init];
rightButton.frame = rightButtonFrame;
[rightButton setTitle:#"Right" forState:UIControlStateNormal];
[rightButton addTarget:self action:#selector(rightButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[yourView addSubview:rightButton];
- (void)leftButtonclicked:(id)sender
{
//Code to turn page left
}
- (void)rightButtonclicked:(id)sender
{
//Code to turn page right
}
I'm going to answer this in swift, but you should be able to translate.
The process is to find the PageControl view, add the two buttons and hide the buttons when appropriate (i.e. no previous button on first page).
I place the buttons on left and right side of PageControl. The default behavior is that touching there does a page back and page forward. So I set the buttons to enabled=false so that touches execute this default behavior.
First we need an enum to help locate buttons. Use values which won't be use elsewhere in view.
enum enumBtnTag: Int {
case tagPrev = 9991
case tagNext = 9992
}
var pageNbr = 0 //Needed to keep track of page being displayed
Now we will add our buttons in ViewDidLoad. First I locate the PageControl, then I look for buttons so as to not create twice. (ViewDidload could be called multiple times)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view is UIPageControl {
let curr:UIPageControl = view as! UIPageControl
curr.backgroundColor = UIColor.clear
curr.currentPageIndicatorTintColor = UIColor.red //Page Dot is red
curr.pageIndicatorTintColor = UIColor.black //Other dots are black
let pcSz = view.frame
let btnSz = CGSize(width: 35, height: 50) //Use your button size
if let _ = self.view.viewWithTag(enumBtnTag.tagNext.rawValue) as? UIButton {}
else { //Next Button not found
let Nbtn = UIButton(frame: CGRect(x: pcSz.width - btnSz.width, y: -15, width: btnSz.width, height: btnSz.height))
Nbtn.setTitle(">>", for: UIControlState.normal)
Nbtn.backgroundColor = UIColor.clear
Nbtn.setTitleColor(UIColor.brown, for: UIControlState.normal)
Nbtn.titleLabel?.font = UIFont(name: enumFontNames.MarkerFelt_Wide.rawValue, size: 60.0)
Nbtn.isEnabled = false //Allows touch to fall through to PageControl
Nbtn.tag = enumBtnTag.tagNext.rawValue
view.addSubview(Nbtn)
}
if let _ = self.view.viewWithTag(enumBtnTag.tagPrev.rawValue) as? UIButton {}
else { //Prev Button not found
let Pbtn = UIButton(frame: CGRect(x: 0, y: -15, width: btnSz.width, height: btnSz.height))
Pbtn.setTitle("<<", for: UIControlState.normal)
Pbtn.backgroundColor = UIColor.clear
Pbtn.setTitleColor(UIColor.brown, for: UIControlState.normal)
Pbtn.titleLabel?.font = UIFont(name: enumFontNames.MarkerFelt_Wide.rawValue, size: 60.0)
Pbtn.isEnabled = false
Pbtn.isHidden = true
Pbtn.tag = enumBtnTag.tagPrev.rawValue
view.addSubview(Pbtn)
}
}
}
}
Then I capture the page that is going to be displayed. The page might not be displayed (user didn't drag far enough), but that is handled later.
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
if let identifier = pendingViewControllers[0].restorationIdentifier {
if let index = pages.index(of: identifier) {
pageNbr = index
}
}
}
Now we modify buttons in didFinishAnimating;
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if finished && completed {
if let button = self.view.viewWithTag(enumBtnTag.tagPrev.rawValue) as? UIButton {
if pageNbr > 0 {
button.isHidden = false
} else {
button.isHidden = true
}
}
if let button = self.view.viewWithTag(enumBtnTag.tagNext.rawValue) as? UIButton {
if pageNbr < pages.count - 1 {
button.isHidden = true
} else {
button.isHidden = false
}
}
}
}
Bonus code: I added a Save function at last page where the Next Button is. You need to set the button is enabled (so it registers the touch) and set a target (what ever function you want to execute); mine is "nextSegue".
and of course remove target when not on last page;
if pageNbr < pages.count - 1 {
//Not on last page. Use next button
button.setTitle(">>", for: UIControlState.normal)
button.removeTarget(self, action: #selector(nextSegue), for: UIControlEvents.touchUpInside)
button.isEnabled = false
} else {
//On last page. Use save button
button.setTitle("S", for: UIControlState.normal)
button.addTarget(self, action: #selector(nextSegue), for: UIControlEvents.touchUpInside)
button.isEnabled = true
}
Hope this helps someone.