I am trying a small project in swift.
I have two labels where i get random numbers each time i click a button.
My question is how can I change the title of the button, to the addition of my two random numbers.
Here is the code:
#IBOutlet var number1: UILabel!
#IBOutlet var number2: UILabel!
#IBOutlet var result: UILabel!
var randomNumber1:Int = 0
var randomNumber2:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func generate(sender: AnyObject) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
}
Try this:
#IBAction func generate(sender: UIButton) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
}
You were missing this line
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
Hope this helps.. :)
btn.setTitle("\(number)", forState: .Normal)
In your current code, you're changing the text of the result label, not the button. To change the UIButton sender's title, change your code to the following:
#IBAction func buttonPress(sender: UIButton) {
let randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
let randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
}
Try this code, instead of anyobject use UIButton
#IBAction func generate(sender: UIButton) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
//Just add this line in the code
sender.setTitle(result.text, forState: UIControlState.Normal)
}
Related
I have a VC like this
for the checkBoxes i have embedded UIButtons and i am changing their image on click. Here's my code
#IBOutlet weak var bestSellerButton: UIButton!
#IBOutlet weak var trendingButton: UIButton!
#IBOutlet weak var lowToHighButton: UIButton!
#IBOutlet weak var highToLowButton: UIButton!
var isBoxClicked = Bool()
func updateCheckImageOnClick(button: UIButton) {
if isBoxClicked == true {
isBoxClicked = false
button.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
else {
isBoxClicked = true
button.setImage(UIImage(), for: UIControlState.normal)
}
}
#IBAction func clickedBestSellerBtn(_ sender: Any) {
updateCheckImageOnClick(button: bestSellerButton)
}
#IBAction func clickedTrendingBtn(_ sender: Any) {
updateCheckImageOnClick(button: trendingButton)
}
likewise for the rest two. Now the check mark image is being set properly every time on click gets set and unset, but i want to restrict the user like if he clicks on best seller btn he's unable to choose the rest, likewise if he clicks trending he can't select any other. How would i do that?
Make the Other button disabled in particular scenario.
isUserInteractionEnabled = false
You could rename updateCheckImageOnClick(button: UIButton) to something generic in order to add some logic inside, like:
func update(button: UIButton) {
isBoxClicked = !isBoxClicked
button.setImage(isBoxClicked ? UIImage(named: "checkmark") : UIImage(), for: UIControlState.normal)
if button == bestSellerButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == trendingButton {
bestSellerButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == highToLowButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
bestSellerButton.isEnabled = false
} else {
bestSellerButton.isEnabled = false
trendingButton.isEnabled = false
highToLowButton.isEnabled = false
}
}
Usama I've implemented a simple button action for all those buttons which may accomplish your need. Here is the step by step implementation -
First, Declare these variables -
var buttonSelected:Bool = false
var selectedButton : UIButton?
Second, Add a single #IBAction for all buttons -
Third, Here is the action method -
#IBAction func btnSelection(_ sender: UIButton) {
if(buttonSelected){
if(selectedButton == sender){
buttonSelected = false
selectedButton = nil
sender.setImage(UIImage(), for: UIControlState.normal)
}
else{
// It's not the previously selected button
//Do your stuff
}
}
else{
buttonSelected = true
selectedButton = sender
sender.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
}
Hope it will help you to start with.
This question already has answers here:
Calling a phone number in swift
(25 answers)
Closed 6 years ago.
I have a Swift app that I'm working on and on the contact us page, there's a bit that shows "Facebook Profile", Telephone Number, Email Address.
I have been told there's a way to have the code set up so when someone clicks on, for example the telephone number, it will open in iPhone phone dialer.
Any ideas where to find the code?
I've been sent this from someone who says they know the code, but when I asked him where the code goes, he said I just have to fiddle.
This is his code:
You need to add this code for each label you need to add for it an action in viewDidLoad:
yourlabel.isUserInteractionEnabled = true
let rc = UITapGestureRecognizer(target: self, action: #selector(YourViewController.yourfunction))
rc.numberOfTapsRequired = 1
rc.numberOfTouchesRequired = 1
yourlabel.addGestureRecognizer(rc)
func yourfunction(recognizer: UITapGestureRecognizer) {
let email = "foo#bar.com"
let url = NSURL(string: "mailto:\(email)")
UIApplication.sharedApplication().openURL(url)
}
And this is my code for the contact page (contactViewController.swift). Can someone have a look for me and help me out?
import UIKit
class contactViewController: UIViewController {
#IBOutlet weak var phone: UILabel!
#IBOutlet weak var mail: UILabel!
#IBOutlet weak var facebook: UILabel!
#IBOutlet weak var instagram: UILabel!
#IBOutlet weak var address: UILabel!
#IBOutlet weak var titleContact: UILabel!
#IBOutlet weak var message: UILabel!
#IBOutlet weak var scroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// setup title
self.title = "Contact us"
// setup NavigationBar Color
self.navigationController?.navigationBar.barTintColor = navigationBarColor
// setup side Bar
if(sideBarPosition == "left"){
self.setupLeftMenuButton()
}
else{
self.setupRightMenuButton()
}
// setup page content
scroll.bounces = false
phone.text = phoneNumber
mail.text = emailAdress
facebook.text = facebookAcount
instagram.text = instgramAcount
address.text = adressLocal
titleContact.text = titleContactus
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 20
let attrString = NSMutableAttributedString(string: messageContact)
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
message.attributedText = attrString
message.textAlignment = NSTextAlignment.center
}
// setup left menu button icon
func setupLeftMenuButton() {
let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "menuleft.png")?.withRenderingMode(.alwaysTemplate), for: UIControlState.normal)
button.addTarget(self, action:#selector(leftDrawerButtonPress), for: UIControlEvents.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width: 30, height: 17) //CGRectMake(0, 0, 30, 30)
button.imageView?.tintColor = iconColor
let barButton = UIBarButtonItem.init(customView: button)
self.navigationItem.leftBarButtonItem = barButton
}
// setup left menu button action
func leftDrawerButtonPress(_ sender: AnyObject?) {
self.evo_drawerController?.toggleDrawerSide(.left, animated: true, completion: nil)
}
// setup right menu button icon
func setupRightMenuButton() {
let button = UIButton.init(type: .custom)
button.setImage(UIImage.init(named: "menuright.png")?.withRenderingMode(.alwaysTemplate), for: UIControlState.normal)
button.addTarget(self, action:#selector(rightDrawerButtonPress), for: UIControlEvents.touchUpInside)
button.frame = CGRect.init(x: 0, y: 0, width: 30, height: 17) //CGRectMake(0, 0, 30, 30)
button.imageView?.tintColor = iconColor
let barButton = UIBarButtonItem.init(customView: button)
self.navigationItem.rightBarButtonItem = barButton
}
// setup right menu button action
func rightDrawerButtonPress(_ sender: AnyObject?) {
self.evo_drawerController?.toggleDrawerSide(.right, animated: true, completion: nil)
}
}
It'll be better if you replace these "labels" with UIButton instead. The different coloring tell users that these string are clickable. Then you can just put everything in to an URL scheme and tell UIApplication.shared to open them:
#IBAction func dialNumber(_ sender: Any) {
let phoneURL = URL(string: "tel://1234567890")!
UIApplication.shared.open(phoneURL, options: [:], completionHandler: nil)
}
#IBAction func sendEmail(_ sender : AnyObject) {
let emailURL = URL(string: "mailto://user#domain.com")!
UIApplication.shared.open(emailURL, options: [:], completionHandler: nil)
}
I have created a class with random questions however the switch statement does not end and the questions keep going in a loop. How do I prevent this from happening and to display another page once all 4 questions randomly have been completed?
import UIKit
class ThirdViewController: UIViewController {
#IBOutlet weak var Question: UILabel!
#IBOutlet weak var Ans1: UIButton!
#IBOutlet weak var Ans2: UIButton!
#IBOutlet weak var Ans3: UIButton!
#IBOutlet weak var Ans4: UIButton!
#IBOutlet weak var Result: UILabel!
#IBOutlet weak var Next: UIButton!
var correctAns = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
Random()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Random(){
var RandomNumber = arc4random() % 4
RandomNumber += 1
switch (RandomNumber) {
case 1:
Question.text = "Where does minal lives?"
Ans1.setTitle("dubai", for: UIControlState.normal)
Ans2.setTitle("london", for: UIControlState.normal)
Ans3.setTitle("india", for: UIControlState.normal)
Ans4.setTitle("japan", for: UIControlState.normal)
correctAns = "2"
break
case 2:
Question.text = "What is my name?"
Ans1.setTitle("Sunil", for: UIControlState.normal)
Ans2.setTitle("Harish", for: UIControlState.normal)
Ans3.setTitle("Rohit", for: UIControlState.normal)
Ans4.setTitle("Minal", for: UIControlState.normal)
correctAns = "4"
break
case 3:
Question.text = "How old are you?"
Ans1.setTitle("22", for: UIControlState.normal)
Ans2.setTitle("32", for: UIControlState.normal)
Ans3.setTitle("21", for: UIControlState.normal)
Ans4.setTitle("28", for: UIControlState.normal)
correctAns = "1"
break
case 4:
Question.text = "What are you studying?"
Ans1.setTitle("Computer Science", for: UIControlState.normal)
Ans2.setTitle("Java", for: UIControlState.normal)
Ans3.setTitle("Bio", for: UIControlState.normal)
Ans4.setTitle("Business", for: UIControlState.normal)
correctAns = "3"
break
default:
Result.text = "Finished"
break
}
}
func Hide(){
Result.isHidden = true
Next.isHidden = true
}
func Unhide(){
Result.isHidden = false
Next.isHidden = false
}
#IBAction func Ans1Action(_ sender: Any) {
Unhide()
if (correctAns == "1"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans2Action(_ sender: Any) {
Unhide()
if (correctAns == "2"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans3Action(_ sender: Any) {
Unhide()
if (correctAns == "3"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans4Action(_ sender: Any) {
Unhide()
if (correctAns == "4"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func NextAction(_ sender: Any) {
Random()
Hide()
}
}
You need to keep a counter of the number of questions already asked. The switch (RandomNumber) will always enter one of the case statements, because RandomNumber is always in the range 1...4.
So, what you need to do is add an instance variable
private var questionCounter = 0
and modify the NextAction function, something like this:
#IBAction func NextAction(_ sender: Any) {
questionCounter += 1
if questionCounter >= 4 {
Result.text = "Finished"
// or whatever...
}
else {
Random()
Hide()
}
}
Keep in mind that by performing an arc4random() each time, the same question may appear more than once.
Create an array of Int indexes from 1 to 4.
Extract an element from the array and display that item. When the array is empty, stop:
Something like this:
var questionIndexes = [1, 2, 3, 4]
if questionIndexes.count > 0 {
let random = Int(arc4random_uniform(Uint32(questionIndexes.count)))
let index = questionIndexes.remove(at: index)
askQuestionAtIndex(index)
}
(You'll have to adjust the code to fit in with your existing code, but that's the basic idea.)
I'm trying to have a custom UIButton become hidden once it's pressed a certain number of times...but I'm at a loss.
Having exhausted my limited knowledge and consulting the Apple's documentation as well as the internet for the better part of 3 hours, I've finally made my way here. I've been learning Swift for a short while now and am making an effort to become more familiar with it. This is my first object-oriented language and it's testing me to say the least. Any help with this more likely than not ridiculously simple problem is very much appreciated.
import UIKit
class ViewController: UIViewController{
#IBOutlet weak var buttonMessageDisplay: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
buttonPressed()
}
var tapcount = 0
let buttonMessage : [String] = [/* long array of strings */]
func buttonPressed() {
let button = UIButton(type:.Custom) as UIButton
button.frame = CGRectMake(0, 0, 100, 100)
button.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
button.backgroundColor = UIColor.redColor()
button.layer.borderColor = UIColor.blackColor().CGColor
button.layer.borderWidth = 3
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.setTitle("", forState: UIControlState.Normal)
button.addTarget(self, action: "buttonPressed", forControlEvents: .TouchUpInside)
view.addSubview(button)
switch tapcount {
case 19...23:
//Hides the button
button.hidden = true
buttonMessageDisplay.text = buttonMessage[tapcount]
case 24...31:
//Unhides the button
button.hidden = false
buttonMessageDisplay.text = buttonMessage[tapcount]
default:
buttonMessageDisplay.text = buttonMessage[tapcount]
}
print("Tap Count: \(tapcount)")
++tapcount
}
Updated with Gesture Recognizer:
import UIKit
class ViewController: UIViewController{
#IBOutlet weak var buttonMessageDisplay: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
buttonMessageDisplay.text = ""
let button = UIButton(type:.Custom) as UIButton
button.frame = CGRectMake(0, 0, 100, 100)
button.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
button.backgroundColor = UIColor.redColor()
button.layer.borderColor = UIColor.blackColor().CGColor
button.layer.borderWidth = 3
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.setTitle("", forState: UIControlState.Normal)
button.addTarget(self, action: "buttonPressed", forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
var tapcount : Int = 0
let buttonMessage : [String] = [/* array of strings */]
#IBAction func userTap(sender: UITapGestureRecognizer) {
print("Tap Received")
if case 19...23 = tapcount {
buttonPressed()
}
}
func buttonPressed() {
switch tapcount {
case 0...18:
buttonMessageDisplay.text = buttonMessage[tapcount]
case 19...23:
//Hides the button
button.hidden = true
buttonMessageDisplay.text = buttonMessage[tapcount]
case 24...32:
//Unhides the button
button.hidden = false
buttonMessageDisplay.text = buttonMessage[tapcount]
case 33...100:
buttonMessageDisplay.text = buttonMessage[tapcount]
default:
print("There are no more messages or an error has been encountered")
}
print("Tap Count: \(tapcount)")
++tapcount
}
}
Your code makes no sense. As #formal says in his answer, you're creating a new button on every tap, which is wrong.
You want to define your button in your Storyboard.
Then you want an IBAction method, which takes the button as a parameter:
#IBAction func buttonPressed(sender: UIButton)
{
++tapcount
if tapcount < 19
{
sender.hidden = true
}
}
Note that if the button you're hiding is the same one the user is tapping, once it is hidden, you're done. The user can't tap a hidden button, so there's no way to un-hide it. (And thus no point in your switch statement)
Your main issue is that you are creating a new button every time you call button pressed. Create an #IBOutlet for your button and just set its hidden property in butPressed (which can be set as an action of the button).
Something like:
class ViewController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBOutlet weak var buttonMessageDisplay: UILabel!
var tapcount = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func butPressed(sender: AnyObject) {
switch tapcount {
case 19...23:
//Hides the button
button.hidden = true
case 24...31:
//Unhides the button
button.hidden = false
default: break
}
print("Tap Count: \(tapcount)")
buttonMessageDisplay.text = "Tap: \(tapcount)"
++tapcount
}
}
The method buttonPressed() creates a new button each time it is called. You should define button as a property similar to buttonMessageDisplay and place the code to initialise it within viewDidLoad().
You should give space between range in case condition:
For example:
(IBAction)buttonTapped:(id)sender {
self.count++;
switch (self.count) {
case 5 ... 23 :
self.button.titleLabel.text = #"disable";
self.button.hidden = true;
break;
default:
break;
}
}
I'm trying to make a play/pause button that toggles between custom images as it is pressed. Here is a snippet of the code.
Everything works fine but the button doesn't change. I've also tried using the .image property instead of the .setBackGroundImage method but then the button just goes blank on click.
Here is the code
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer = AVAudioPlayer()
var pauseImage:UIImage?
var playImage:UIImage?
#IBOutlet weak var btnPlayPause: UIBarButtonItem!
#IBOutlet weak var sldVolume: UISlider!
#IBAction func sldVolumeChanged(sender: AnyObject) {
audioPlayer.volume = sldVolume.value
}
#IBAction func actPressedPlayPause(sender: AnyObject) {
if audioPlayer.playing {
audioPlayer.pause()
btnPlayPause.setBackgroundImage(playImage, forState: .Normal, barMetrics: .Default)
} else {
audioPlayer.play()
btnPlayPause.setBackgroundImage(pauseImage, forState: .Normal, barMetrics: .Default)
}
}
#IBAction func actStopPressed(sender: AnyObject) {
audioPlayer.stop()
audioPlayer.currentTime = 0
}
override func viewDidLoad() {
super.viewDidLoad()
var pauseImagePath = NSBundle.mainBundle().pathForResource("pause", ofType: "png")
pauseImagePath = pauseImagePath!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
pauseImage = UIImage(contentsOfFile: pauseImagePath!)
var playImagePath = NSBundle.mainBundle().pathForResource("play", ofType: "png")
playImagePath = playImagePath!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
playImage = UIImage(contentsOfFile: pauseImagePath!)
var audioPath = NSBundle.mainBundle().pathForResource("minuetcminor", ofType: "mp3")
audioPath = audioPath!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
var error : NSError? = nil
audioPlayer = AVAudioPlayer(contentsOfURL: NSURL(string: audioPath!), error: &error)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
had the same problem here! Had two of us confused as to why it wasn't working, I think it's a change in Swift 2/Xcode 7 beta
Just do this:
btnPlayPause.image = UIImage(named: "myImage.png")
Hope that helps!
Seems like this question has got a lot of strange answers. The truth is there's no non-hacky way to change an image in already existing UIBarButtonItem. Instead, unfortunately, you have to re-create it.
I've made a helper method to do this:
func changeBarButtonItemImage(_ item: UIBarButtonItem, image: UIImage, navItem: UINavigationItem) -> UIBarButtonItem? {
let buttonItem = UIBarButtonItem(image: image, style: item.style, target: item.target, action: item.action)
buttonItem.isEnabled = item.isEnabled
if let leftIndex = navItem.leftBarButtonItems?.index(of: item) {
var items: [UIBarButtonItem] = navItem.leftBarButtonItems!
items[leftIndex] = buttonItem
navItem.leftBarButtonItems = items
return buttonItem
}
if let rightIndex = navItem.rightBarButtonItems?.index(of: item) {
var items: [UIBarButtonItem] = navItem.rightBarButtonItems!
items[rightIndex] = buttonItem
navItem.rightBarButtonItems = items
return buttonItem
}
return nil
}
Usage:
if let image = UIImage(named: showingFilter ? "icon_filter_active.png" : "icon_filter.png") {
if let buttonItem = changeBarButtonItemImage(self.filterButton, image: image, navItem: navigationItem) {
self.filterButton = buttonItem
}
}
Take note that I also copy isEnabled property, because, in my case, in some situations, I was changing button icon while in the disabled state.
The #IBAction should use sender as UIButton instead of AnyObject or Any. Also, once that is done, the button can be directly accessed from inside the function using sender. (This is Swift 3)
#IBAction func actPressedPlayPause(sender: UIButton) {
if audioPlayer.playing {
audioPlayer.pause()
sender.setBackgroundImage(UIImage(named: "playimage.png"), for: .normal)
} else {
audioPlayer.play()
sender.setBackgroundImage(UIImage(named: "pauseimage.png"), for: .normal)
}
}
Try using below line of code:
btnPlayPause.setImage(image, forState: .Normal)
this works for me.