When push the UIButton, change image in the image view - ios

I'm new to Swift and I am trying the make a button. I want to when i push the button start the timer and change image in the image view.
My code;
#IBOutlet weak var label: UILabel!
func start()
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController2.updateTime as (ViewController2) -> () -> ())), userInfo: nil, repeats: true)
}
func updateTimer () {
count += 1
let hours = Int(count) / 3600
let minutes = Int(count) / 60 % 60
let seconds = Int(count) % 60
label.text = String(format: "%02i:%02i:%02i",hours,minutes,seconds)
}
func reset()
{
timer.invalidate()
count = 0
label.text = "00:00:00"
}
#IBAction func buttonPressed(sender : UIButton)
{
if sender.currentTitle == " "
{
sender.setTitle("", for: UIControlState.normal)
reset()
}
else
{
sender.setTitle(" ", for: UIControlState.normal)
start()
}
}
#IBOutlet weak var image: UIImageView!
#IBAction func tick(sender: UIButton)
{
if checked
{
sender.setImage( UIImage(named:"Rectangle1.png"), for: [])
checked = false
}
else
{
sender.setImage(UIImage(named:"Rectangle2.png"), for: [])
checked = true
}
}
Unfortunately when i push the button, changes the picture of the button. How can i change the image in the image view?

You are setting the senders image.. which is your UIButton.. change this part of your code
wrong:
sender.setImage(UIImage(named:"Rectangle1.png"), for: [])
...
sender.setImage(UIImage(named:"Rectangle2.png"), for: [])
right:
image.image = UIImage(named:"Rectangle1.png")
...
image.image = UIImage(named:"Rectangle2.png")

Define the button as a IBOutlet and set a new image:
button.setImage(UIImage(named: "Rectangle1.png"), for: .normal)

Related

Long Press Recognize Gesture via Button - Swift 3

I'm new to Swift and I'm trying to make timer(in the label) that starts with a long press on the button. At the same time I want to change the long press button image when press the long press button. I leave button, I want the button revert back.
What might be wrong?
#IBOutlet weak var myBtn: UIButton!
func initGesture()
{
{ let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap(_:)))
myBtn.addGestureRecognizer(longGesture)
}
}
func TimerAction()
{
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(longTap), userInfo: nil, repeats: false)
myBtn.setImage(UIImage(named: "xxx.png"), for: .normal)
}
#IBOutlet weak var lbl: UILabel!
func start()
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController2.updateTime as (ViewController2) -> () -> ())), userInfo: nil, repeats: true)
}
func updateTimer () {
count += 1
let hours = Int(count) / 3600
let minutes = Int(count) / 60 % 60
let seconds = Int(count) % 60
label.text = String(format: "%02i:%02i:%02i",hours,minutes,seconds)
}
func reset()
{
timer.invalidate()
count = 0
label.text = "00:00:00"
}
You can get TouchUpInside and TouchUpOutside also TouchDown action of button don't use the gesture.
class ViewController: UIViewController {
#IBOutlet weak var lbl: UILabel!
#IBOutlet weak var myBtn: UIButton!
var timer: NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
myBtn.addTarget(self, action: "buttonDown:", forControlEvents: .TouchDown)
myBtn.addTarget(self, action: "buttonUp:", forControlEvents: [.TouchUpInside, .TouchUpOutside])
}
func buttonDown(sender: AnyObject) {
singleFire()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "rapidFire", userInfo: nil, repeats: true)
}
func buttonUp(sender: AnyObject) {
timer.invalidate()
count = 0
label.text = "00:00:00"
}
func singleFire() {
myBtn.setImage(UIImage(named: "xxx.png"), for: .normal)
}
func rapidFire() {
count += 1
let hours = Int(count) / 3600
let minutes = Int(count) / 60 % 60
let seconds = Int(count) % 60
label.text = String(format: "%02i:%02i:%02i",hours,minutes,seconds)
}
}
You should implement button events instead of using the gesture recognisers here. The button events i talk about are TouchDown and TouchUpInside. TouchDown will tell you when a button is being pressed and touchupinside will tell you when the user lifted their finger from button.
So you will change the button image and start your timer on touchdown event. Then you will revert back on touchupinside event.
https://developer.apple.com/documentation/uikit/uicontrolevents
Try this,
set first the image of the button depending on its state.
self.arrowIcon.setImage(UIImage(named: "normalImage.png"), for: .normal)
self.arrowIcon.setImage(UIImage(named: "pressedImage.png"), for: .highlighted)

How to make a timer that starts with a long press on the button?

I'm currently learning Swift and iOS programming. I want to make a timer that starts with a long press on the button. At the same time I want to change the UIButton image. I leave button, I want the button revert back. Is this possible?
You absolutely can do this. You have to add LongPressGestureRecognizer:
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(yourAction))
button.addGestureRecognizer(longPress)
And then in your func start the timer and change the button's image:
func yourAction(){
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
button.setImage(UIImage(named: "yourImage"), for: .normal)
}
func timerAction(){
//Do whatever you want
}
You need to implement your own solution for this, something along the lines
1- User touches down (UIControlEvent touchDown), you start a time that fires every x secs/millisecs
2- Timer will fire the action over and over
3- User touches up UICOntrolEvent touchUp, you cancel your timer
So you bind those 2 events to different functions, and start/kill your timers with appropriate actions
How that helps
I will add a code for demonstration:
#IBOutlet var button: UIButton!
var timer: Timer!
var speedAmmo = 100
#IBAction func buttonDown(sender: AnyObject) {
singleFire()
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector:#selector(rapidFire), userInfo: nil, repeats: true)
}
#IBAction func buttonUp(sender: AnyObject) {
timer.invalidate()
}
func singleFire() {
if speedAmmo > 0 {
speedAmmo -= 1
print("bang!")
} else {
print("out of speed ammo, dude!")
timer.invalidate()
}
}
func rapidFire() {
if speedAmmo > 0 {
speedAmmo -= 1
print("bang!")
} else {
print("out of speed ammo, dude!")
timer.invalidate()
}
}
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action:#selector(buttonDown(sender:)), for: .touchDown)
button.addTarget(self, action:#selector(buttonUp(sender:)), for: [.touchUpInside, .touchUpOutside])
}
Please try and let me know!

How to end a switch case

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.)

SIGABRT error when using NSTimer, Swift 2 Xcode 7

I have a function that flashes a button. The function is inside a for i loop, which is in the viewDidLoad function. I also have an NSTimer that calls the function repeatedly flashing a different button each time. However I am getting a SIGABRT error when I run this. If you are going to ask, I have made sure that the connections with my buttons are solid, no cut off connections.
var computerChoices = [Int](count: 11, repeatedValue: 0)
var randomIndex = 0
var pcChoice = 0
var lit = [b0o,b1o,b2o,b3o,b4o,b5o,b6o,b7o,b8o]
var litIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
for i in 1...10{
print(randomIndex)
print(computerChoices)
var buttonChoice = lit[randomIndex]
randomIndex = Int(arc4random_uniform(UInt32(lit.count)))
computerChoices[i] = randomIndex
print("yoyoyo")
func flashingButtons(){
var one = computerChoices[pcChoice]
lit[one].setImage(UIImage(named: "redb.png"), forState: UIControlState.Normal)
pcChoice += 1
}
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("flashingButtons"), userInfo: nil, repeats: true)
}
}
Put out the flashingButtons function out of the viewDidLoad. The timer find the function and couldn't find it if it is embedded.
override func viewDidLoad() {
super.viewDidLoad()
for i in 1...10{
print(randomIndex)
print(computerChoices)
var buttonChoice = lit[randomIndex]
randomIndex = Int(arc4random_uniform(UInt32(lit.count)))
computerChoices[i] = randomIndex
print("yoyoyo")
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("flashingButtons"), userInfo: nil, repeats: true)
}
}
func flashingButtons(){
var one = computerChoices[pcChoice]
lit[one].setImage(UIImage(named: "redb.png"), forState: UIControlState.Normal)
pcChoice += 1
}
You should put flashingButtons() out side viewDidLoad. And in it you make sure that out of range don't happen because pcChoice increase over time.
func flashingButtons(){
var one = computerChoices[pcChoice]
lit[one].setImage(UIImage(named: "redb.png"), forState: UIControlState.Normal)
if pcChoice >= 10 {
pcChoice = 0
return
}
pcChoice += 1
}

Button with constraints inside PersonCell hides half of the button Swift

Created a button inside a personCell which either shows Follow / Unfollow.
I've added the following constraints to the button:
Align Center Y to: Superview
Height = 43
Trailing space to: Superview
With or without the constraints it still cuts of a side of the button.
If the button was supposed to display "follow" it would only show "ow"
Code for PersonCell
class PersonCell: UITableViewCell {
#IBOutlet weak var followButton: UIButton!
var isFollowing: Bool?
var user: PFUser?
{
didSet
{
self.configure()
}
}
override func awakeFromNib()
{
super.awakeFromNib()
self.isFollowing = false
self.followButton?.hidden = true
}
override func prepareForReuse()
{
super.prepareForReuse()
self.isFollowing = false
self.followButton?.hidden = true
self.textLabel?.text = ""
self.user = nil
}
func configure()
{
if let constUser = user
{
self.textLabel?.text = constUser.username
// are we following this person?
NetworkManager.sharedInstance.isFollowing(constUser, completionHandler: {
(isFollowing, error) -> () in
if let _ = error
{
// Alert the user, or otherwise modify the UI
}
else
{
self.isFollowing = isFollowing
if isFollowing == true
{
let image = UIImage(named: "UnfollowButton")
self.followButton?.setImage(image, forState: .Normal)
}
else
{
let image = UIImage(named: "FollowButton")
self.followButton?.setImage(image, forState: .Normal)
}
self.followButton?.hidden = false
}
})
}
}
#IBAction func didTapFollow(sender: UIButton)
{
self.followButton?.enabled = false
let newValue = !(self.isFollowing == true)
NetworkManager.sharedInstance.updateFollowValue(newValue, user: self.user!) { (error) -> () in
self.followButton?.enabled = true
let image = (newValue == true) ? UIImage(named: "UnfollowButton") : UIImage(named: "FollowButton")
self.followButton?.setImage(image, forState: .Normal)
self.isFollowing = newValue
}
}
}
Im not yet allowed to post images but see this if you need to view how it looks:
http://postimg.org/image/jnf47mnr1/
Thankx in advance!

Resources