how to iterate through functions with button press in Swift - ios

I'm learning swift and building an ARApp but can't seem to understand how to iterate through a few functions with every separate button press. I have created 3 func with animation built in and want to press the button once and funcAnimation#1 activate then tap button again to proceed to funcAnimation#2 and so forth.
#IBAction func nextAnimation(_ sender: UIButton) {
funcAnimation#1()
funcAnimation#2()
funcAnimation#3()
}
of course the problem here is that they all activate at once. I would like to iterate only on button press for each individual press. In addition I would also like to have a backButton that reverses the current animation to previous animation. I read in Apple's documentation that there is a addTarget method but I don't understand how it works or how to implement it. Please Help!

Your code should like this :
// You can define this variable globally...
var counter = 0
#IBAction func nextAnimation(_ sender: UIButton) {
if (counter == 0) {
funcAnimation1()
// Increase counter count by 1 and you can add this line to completion of animation.
// You can also disable your button interaction until your animation gets complete and that way you can handle your UI
count += 1
}
else if (counter == 1) {
funcAnimation2()
// Increase counter count by 1 and you can add this line to completion of animation.
count += 1
}
else if (counter == 2) {
funcAnimation3()
// set your counter to 0 again to loop through your animation.
counter = 0
}
}
Your Back Action should look like this:
#IBAction func backAnimation(_ sender: UIButton) {
if (counter == 0) {
funcAnimation1()
// set your counter to 2 again to loop through your animation.
count = 2
}
else if (counter == 1) {
funcAnimation2()
// decrease counter count by 1 and you can add this line to completion of animation.
// You can also disable your button interaction until your animation gets complete and that way you can handle your UI
count -= 1
}
else if (counter == 2) {
funcAnimation3()
// decrease counter count by 1 and you can add this line to completion of animation.
count -= 1
}
}

Another way!
Just set tag of button 1 (Ex. btnObj.tag=1)
And manage method(s) in action of the button like
My suggestion is also manage flag for animation like if 1st animation is in process then 2nd will be waiting for finish and after finishing 1st animation, button will be clicked so your animation will not mismatch.
var isAnimated = false;
#IBAction func myAnimationMethod(_ sender: UIButton) {
if isAnimated {return} // Or display appropriate message by alert
if (sender.tag == 1) {
isAnimated=true
funcAnimation1(...Your Code... After finish to set isAnimated=false)
sender.tag = 2
}
else if (sender.tag == 2) {
isAnimated=true
funcAnimation2(...Your Code... After finish to set isAnimated=false)
sender.tag = 3
}
else if (sender.tag == 3) {
isAnimated=true
funcAnimation3(...Your Code... After finish to set isAnimated=false)
sender.tag = 1
}
}

You can forward your animations and go back to previous animation state through a back button like this .
Step 1 : Declare two integer type variables
var tapCount = 0 //For forwarding your animations from first to third
var currentAnimation = 0 // For reversing the animation from current animation
Step 2 : In your IBAction Function
#IBAction func nextAnimation(_ sender: Any)
{
if tapCount == 0
{
if currentAnimation == 1
{
Animation2()
}
else
{
Animation1()
}
tapCount += 1
}
else if tapCount == 1
{
if currentAnimation == 2
{
Animation3()
}
else
{
Animation2()
}
tapCount += 1
}
else if tapCount == 2
{
if currentAnimation == 3
{
Animation1()
}
else
{
Animation3()
}
tapCount = 0
}
}
Step 3 : In your functions
func Animation1() {
currentAnimation = 1
print("First Animation")
}
func Animation2() {
currentAnimation = 2
print("Second Animation")
}
func Animation3() {
currentAnimation = 3
print("third Animation")
}
Step 4: Lastly For Reversing the animation from current state
#IBAction func backAnimation(_ sender: Any)
{
if currentAnimation == 2
{
Animation1()
}
else if currentAnimation == 3
{
Animation2()
}
else
{
}
tapCount = 0
}
Hope it helps !!
For addTarget(_:action:for:) method , this can be done without connecting a IBAction and declaring it in viewWillAppear or viewDidLoad as required.It will Associates a target object and action method with the control.
For example :
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
nextButton.addTarget(self, action: #selector(self. nextAnimation), for: .touchUpInside) //Declared outlet as nextButton
backButton.addTarget(self, action: #selector(self. backAnimation), for: .touchUpInside) //Declared outlet as backButton and this adds a target
}
#objc func nextAnimation(sender: UIButton) {
// Do your stuff for next animation
}
#objc func backAnimation(sender: UIButton) {
// Do your stuff for previous animation
}

Related

How do you disable the action of a button in Swift?

I am not sure about how to do this. I am trying to allow it so that when the function "end" happens, the score can no longer increase when button is tapped.
#IBAction func Button(_ sender: UIButton) {
score += 1
}
func end() {
score += 0
}
You can disable the button
func end() {
yourButton.isEnabled = false
}
There are two ways:
yourButton_Outlet_Name.isEnabled = false
yourButton_Outlet_Name.isUserInteractionEnabled = false
Make sure to use it on the button outlet, not the UIButton class

make 3 random elements in the array invisible

I have 5 buttons in an array I want to make random three of these invisible when pressed on button. so the last two buttons will be visible
I tried like this:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
let buttons:[UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
let randomNumber = Int(arc4random_uniform(UInt32(3)))
buttons[randomNumber].isHidden = !buttons[randomNumber].isHidden
}
but it takes first elements [0,1,2] and only 1 button is invisible at each press
You are currently only selecting one button. Change that to a loop to select 3. Remove the selected button from the array and make it invisible. Finally, make the remaining buttons visible:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
var buttons:[UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
// Select 3 buttons randomly and hide them
for _ in 1...3 {
let randomNumber = Int(arc4random_uniform(UInt32(buttons.count)))
let button = buttons.remove(at: randomNumber)
button.isHidden = true
}
// Make the remaining buttons visible
for button in buttons {
button.isHidden = false
}
}
I've just written a neat extension to get a random elements from an array:
extension Array {
func randomItems(count: Int) -> [Element] {
guard count <= self.count else { fatalError() }
var notUsedElements: [Element] = self
var randomElements: [Element] = []
while randomElements.count != count {
randomElements.append(notUsedElements.remove(at: Int(arc4random_uniform(UInt32(notUsedElements.count)))))
}
return randomElements
}
}
Using this you can achieve what you want this way:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
let buttons:[UIButton] = [buttonA, buttonB, buttonC, buttonD, buttonE]
// make sure all are visible at the beginning
buttons.forEach { (button) in
button.isHidden = false
}
// hide random 3:
buttons.randomItems(count: 3).forEach { (button) in
button.isHidden = true
}
}

How to repeat or re- select the selected segment on HMSegmentedControl?

In HMSegmentedControl, I want to perform repeated segment selection. Means If a segment is selected already, If it's press or select again it should perform/ reload the next functions on the basis of segment selection.
In HMSegmentedControl.swift file, there is tapped(segmentButton:) function in which you can just change indexChanged bool variable to true or you can remove indexChanged variable from if condition then every time you tap selected tab event will occures. Here is actual function code :
Swift
func tapped(segmentButton sender: UIButton) {
let newIndex = sender.tag
//let indexChanged: Bool = newIndex != selectedSegmentIndex
let indexChanged: Bool = true
selectedSegmentIndex = newIndex
if let indexChangedHandler = indexChangedHandler, indexChanged == true {
indexChangedHandler(selectedSegmentIndex)
}
setSelectedSegmentIndex(newIndex, animated: true)
}
OR
func tapped(segmentButton sender: UIButton) {
let newIndex = sender.tag
selectedSegmentIndex = newIndex
if let indexChangedHandler = indexChangedHandler {
indexChangedHandler(selectedSegmentIndex)
}
setSelectedSegmentIndex(newIndex, animated: true)
}
Objective-C
you can remove segment != self.selectedSegmentIndex condition in this method - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
//if (segment != self.selectedSegmentIndex && segment < sectionsCount) {
if (segment < sectionsCount) {
// Check if we have to do anything with the touch event
if (self.isTouchEnabled)
[self setSelectedSegmentIndex:segment animated:self.shouldAnimateUserSelection notify:YES];
}
NOTE : commented line (1st line) is old code and 2nd line is new code.

Recognize which View calls the Tap function

I know how to add tappability to the UIImageView, however, there are 2 image views and I want to distinguish them to call the correct function. However, I can't seem to get the correct sender.
func addTappability (view imageView:UIImageView){
//add tapping function for image
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action:#selector(IdCardViewController.imageTapped(_:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
func imageTapped(_ sender: UIImageView) {
//Problem here, can't get correct sender
if ( sender == photoImageViewLeft) {
//do one thing
}else {
//do the other
}
}
Replace your function with this:
func imageTapped(_ sender: UITapGestureRecognizer) {
if let imageView = sender.view as? UIImageView {
if ( imageView == photoImageViewLeft ) {
print("Image1 Tapped")
}else {
print("Image2 Tapped")
}
}
}
You need to add tag where you're adding imageViews either in storyboard or in code.
then in your imageTapped() method compare them -
func imageTapped(_ sender: UIImageView) {
//Problem here, can't get correct sender
if ( sender.tag == 1) {
//do one thing
}else if(sender.tag ==2){
//do the other
}
}

Disabling a Button in Swift

So I'm new to Swift, but trying to figure out how to disable this button when it is pressed. I have the following:
#IBAction func IBbtnUpdateTap(sender: UIButton){
if imageNumber == 0 {
IBbtnUpdateTap.enabled = false
}
I'm not sure why it's giving me problems. Any ideas?
IBbtnUpdateTap isn't the button. The button is sender
#IBAction func IBbtnUpdateTap(sender: UIButton){
if imageNumber == 0 {
sender.enabled = false
}

Resources