Reputation: 115
I created a class and function for a button:
class FloatingActionButton: UIButtonX {
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
UIView.animate(withDuration: 0.3, animations: {
if self.mapTypeButton.transform == .identity {
self.mapTypeButton.transform = CGAffineTransform(rotationAngle: 45 * (.pi / 180)) .
} else {
self.mapTypeButton.transform = .identity
return super.beginTracking(touch, with: event)}
Now I'm in another class ViewController and I want to call my function (refer to update for why I want to call my function)
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
self.closeMapType()
FloatingActionButton().beginTracking(touch: UITouch, with: UIEvent?)
return true
}
but I have been told that beginTracking is not a function type that can be called.
UPDATE:
I set up the button on the Storyboard and connected it to a pointer. Right now, the button is situated like this (Photo 1), (I apologize I don't have enough reputation points to post a photo yet). When I tap it in the simulator, it changes to this (Photo 2), and when I tap it again, it changes back to its default state. All of this functionality is set up in the FloatingActionButton class
.
It works to put the UIView.animate(etc.)
inside func searchBarShouldBeginEditing
but I'd like to know if I can call the UIView.animate(etc.)
to reduce redundancy.
What I want to do now is make it so that when I tap the searchBar, if the button is in the rotated state (Photo 2), it will rotate back to the original state (Photo 1). I've created:
@IBOutlet weak var mapTypeButton: FloatingActionButton!
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
UIView.animate(withDuration: 0.3, animations: {
if self.mapTypeButton.transform == .identity {
return
} else {
self.mapTypeButton.transform = .identity
})
return true
}
and it does exactly what I'm looking for. Rather than calling the function, I just added the function actions into the new function. Thanks for all the help
Upvotes: 0
Views: 611
Reputation: 131491
It sounds like you don't really understand object-oriented programming.
A button object should not exist in a vacuum. A button is a user interface element, and it belongs on-screen somewhere.
This code:
FloatingActionButton().beginTracking(touch: UITouch, with: UIEvent?)
Creates a brand-new FloatingActionButton
, tells it to begin tracking touches, and then forgets about it. It never has any ties to anything. Nobody owns it, so when the searchBarShouldBeginEditing function returns, the button object gets deallocated.
Is this button supposed to be displayed on-screen somewhere, and track touches? If so, you need to decide what view should host it, and add it to that view. You will also need to set up AutoLayout constraints so that it gets placed in it's parent view.
In general, it's easier (and usually better) to create your user interface in Storyboards, and place them in the view hierarchy that way. To help you with that, though, you need to explain how this button fits into your user interface.
Based on your updates, you want to change the settings on a button that is in your storyboard. (Note that the call you're trying to do on the button is very likely wrong, but nevertheless I'll walk you thorough how you get a pointer (an IBOutlet
) to a button or other view so you can configure it.)
The way you do that is to set up the storyboard in the main editor window, and then open the source file for the view controller that contains the button in the "assistant editor." I suggest selecting the "assistant editor on bottom" option for this.
Now you hold down the control key, press down on your button, and control-drag from the button into the inside of your view controller class, up at the top near the other variables. Xcode will offer to create an IBOutlet to your button. In the resulting dialog, change the type of "sender" to your button type (a "FloatingActionButton".) If Xcode won't let you do that, see if you can select "UIButton" instead. Give it a name like "myFloatingButton".
Now change your code from
FloatingActionButton().beginTracking(touch: UITouch, with: UIEvent?)
to
myFloatingButton.beginTracking(touch: UITouch, with: UIEvent?)
What you've done is to create an instance variable myFloatingButton
in your view controller. When the OS loads the view controller's views, it will save a pointer to your floating button in that instance variable. Once your view has loaded (once your viewDidLoad()
method is called) you can assume that your variable myFloatingButton
points to your button, and can then call your method to configure it.
As Hasan pointed out in his answer, it doesn't make sense for you to call beginTracking(_:with:)
on your button. That is a method of UIButton
(actually of the button's ancestor class, UIControl
) that the system calls internally when the user touches the button.
You'll have to explain what you're trying to do in order for us to be able to help you to do it.
Upvotes: 1
Reputation: 24195
I will ellaborate on @Duncan answer.
The overridden beginTracking
function is not type of function that get called by your code. It get called when its event occure.
Obviously you want to use a button of type FloatingActionButton
. What you need to do is to drag-and-drop a UIButton to your UIViewController using the storyboard. Select that button and change its type to FloatingActionButton
by going to the identity inspector at the right pane and change the value in the Class field to FloatingActionButton
.
Logically, the beginTracking
will be called automatically when its event occurs. Unless, there is a boolean type property needs to be turned on in that FloatingActionButton
.
Upvotes: 1