Animate view's subViews is not working with CAGradientLayer [closed] - ios

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I would like to use CAGradientLayer in my app. I'm inserting a CAGradientLayer at index 0 of the viewController's view's sublayers:
class ViewController: UIViewController {
var label: UILabel!
override func viewDidLoad() {
let width = view.frame.size.width
let height = view.frame.size.height
super.viewDidLoad()
label = UILabel(frame: CGRect(x: 30, y: 80, width: width/4, height: height/20))
label.backgroundColor = UIColor.yellow
label.textColor = UIColor.white
label.text = "label"
label.alpha = 0
view.addSubview(label)
let hideButton = UIButton.init(type: .system)
hideButton.frame = CGRect(x: width/2 - 15, y: label.frame.origin.y + 50, width: width/4, height: 30)
hideButton.setTitle("Hide", for: .normal)
hideButton.backgroundColor = UIColor.red
hideButton.addTarget(self, action: #selector(ViewController.fadeOutLabel), for: .touchUpInside)
view.addSubview(hideButton)
let gradientButton = UIButton.init(type: .system)
gradientButton.frame = CGRect(x: width/2 - 15, y: hideButton.frame.origin.y + 50, width: width/4, height: 30)
gradientButton.setTitle("add gradient", for: .normal)
gradientButton.backgroundColor = UIColor.red
gradientButton.addTarget(self, action: #selector(ViewController.updateSubviews), for: .touchUpInside)
view.addSubview(gradientButton)
}
func updateSubviews() {
UIView.animate(withDuration: 0.3, animations: {
self.label.alpha = 1
let gradientSublayer = self.makeGradientLayer()
self.view.layer.insertSublayer(gradientSublayer, at: 0)
}, completion: nil)
}
func makeGradientLayer() -> CAGradientLayer{
let gradientLayer = CAGradientLayer()
gradientLayer.frame = UIScreen.main.bounds
let primaryColor = UIColor.yellow
let secondaryColor = UIColor.green
gradientLayer.colors = [primaryColor.cgColor, secondaryColor.cgColor]
return gradientLayer
}
func fadeOutLabel(){
print("touch received")
UIView.animate(withDuration: 0.3, animations: {
self.label.alpha = 0
}) { (finished) in
print("animation finished")
}
}
}
However, I have other UI elements on a screen, and they are visible, but when I try to add some animations (animate label's alpha on tapping a button or changing its text), it doesn't work. The button's selector fires, then the animation block executes... but nothing happens. I've tried the most obvious solution - creating a separate view and add it as a subview, but the result won't change. All the subviews on the controller are being added to the main view in the viewDidLoad. Maybe I'm missing something about CALayers?

In my original code I was adding labels and other subviews in viewWillLayoutSubviews(). I moved everything to viewDidLoad() and animations started to work. Unfortunately, I wasn't able to reproduce that in a sample project. Still not sure were I was wrong.

Related

Adding image in the Navigation Bar

I was wondering the best approach to put an image into the navigation bar.
My initial thought was to create a cocoa touch class for UINavigationController and set it up that way, but I can seem to get it to working using the below code:
class NavBarImage: UINavigationController {
override func awakeFromNib() {
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.setupView()
}
func setupView()
{
let navController = navigationController!
let image = #imageLiteral(resourceName: "BarTabsNavLogoWhite")
let imageView = UIImageView(image: image)
let bannerWidth = navController.navigationBar.frame.size.width
let bannerHeight = navController.navigationBar.frame.size.height
let bannerX = bannerWidth / 2 - image.size.width / 2
let bannerY = bannerHeight / 2 - image.size.height / 2
imageView.frame = CGRect(x: bannerX, y: bannerY, width: bannerWidth,
height: bannerHeight)
imageView.contentMode = .scaleAspectFit
navigationItem.titleView = imageView
}
}
I keep getting an "unexpectedly found nil while unwrapping an optional value" on let navController = navigationController!.
However, this method has also been working for me too. I created a cocoa touch class for UINavigationBar and used this code below:
import UIKit
class NavBarImg: UINavigationBar {
override init(frame: CGRect) {
super.init(frame: frame)
initialise()
}
required init(coder aDecoder: NSCoder){
super.init(coder: aDecoder)!
initialise()
}
func initialise(){
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 225, height: 40))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named:"BarTabsNavLogoWhite")
imageView.image = image
imageView.frame.origin = CGPoint(x: self.superview?.center.x, y: self.superview?.center.y)
addSubview(imageView)
}
}
The only problem with this is that on different iPhones I cant figure out how to get the image to always be centered on any device using CGPoint.
Then for the last method I found and implemented is done by the code below:
#IBDesignable class test: UINavigationBar { #IBInspectable var imageTitle: UIImage? = nil {
didSet {
guard let imageTitle = imageTitle else {
topItem?.titleView = nil
return
}
let imageView = UIImageView(image: imageTitle)
imageView.frame = CGRect(x: 0, y: 0, width: 40, height: 30)
imageView.contentMode = .scaleAspectFit
topItem?.titleView = imageView
}
}
}
I really like this method because with the IBDesignable function you can see it in the storyboard. However the way I have my viewcontrollers set up with tableviews, after i go past the first view controller, the navigation bar image disappears in all other view controllers when I run the simulator.
Looking for advice to see which method is the best approach and how to possibly solve the problems I am having. Or if anyone has a different method that they have found that works, id love to see how it works!
you can simply add a image or customize the barbutton as follows:
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "icon_right"), for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 53, height: 31)
button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32)//move image to the right
let label = UILabel(frame: CGRect(x: 3, y: 5, width: 20, height: 20))
label.font = UIFont(name: "Arial-BoldMT", size: 16)
label.text = "title"
label.textAlignment = .center
label.textColor = .black
label.backgroundColor = .clear
button.addSubview(label)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.rightBarButtonItem = barButton

iOS Swift 3 - Remove Overlay UIView after Panel Tap

I am very new to swift and I am stuck with the task described in the title.
My Problem:
I am building a product page programmatically, consisting of a few simple details and an offer button. Tapping offer button brings up an overlay on the view with some other details. You click "Ok" and the overlay disappears.
All good except the overlay does not disappear!
What I have tried:
func hideOverlay(_ sender: UIButton) {
containerView.backgroundColor = UIColor.white
buttonView.backgroundColor = UIColor.white
for subview in overlayView.subviews {
subview.removeFromSuperview()
}
}
Function is called on tapping the button within the overlayView. I will include the showOverlay function(working).
func showOverlay(_ sender: UIButton) {
//Load overlay view
let overlayHeight : CGFloat = 500
let overlayWidth : CGFloat = 290
let overlayView = UIView(frame: CGRect(x: centreView(masterView: view.frame.width, subView: overlayWidth), y: 64 + centreView(masterView: (view.frame.height - 64), subView: overlayHeight), width: overlayWidth, height: overlayHeight))
overlayView.backgroundColor = UIColor.white
let overlayTitle = UILabel(frame: CGRect(x: 0, y: 0, width: overlayWidth, height: overlayHeight*1/5))
overlayTitle.text = "Offer Taken"
overlayTitle.font = UIFont.boldSystemFont(ofSize: 35)
overlayTitle.textAlignment = .center
overlayView.addSubview(overlayTitle)
let overlayButtonView = UIView(frame: CGRect(x: 0, y: 0 + (overlayHeight * 4/5), width: overlayWidth, height: overlayHeight * 1/5))
overlayButtonView.backgroundColor = UIColor.red
let buttonWidth : CGFloat = 100
let buttonHeight : CGFloat = 35
let overlayButton = UIButton(type: UIButtonType.system)
overlayButton.frame = CGRect(x: centreView(masterView: overlayWidth, subView: buttonWidth), y: overlayButtonView.frame.origin.y + centreView(masterView: overlayButtonView.frame.height, subView: buttonHeight), width: buttonWidth, height: buttonHeight)
overlayButton.backgroundColor = UIColor.blue
overlayButton.setTitle("OK",for: .normal)
overlayButton.setTitleColor(UIColor.white, for: .normal)
overlayButton.setTitle("Offer Taken", for: .highlighted)
overlayButton.setTitleColor(UIColor.white, for: .highlighted)
overlayButton.addTarget(self, action: #selector(self.hideOverlay(_:)), for: .touchUpInside)
overlayView.addSubview(overlayButtonView)
overlayView.addSubview(overlayButton)
containerView.backgroundColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 0.5)
buttonView.backgroundColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 0.5)
view.addSubview(overlayView)
}
I have tried
overlayView.removeFromSuperview()
after the for loop, but I fear that overlayView.subviews is not correctly filled with the views I expect.
I appreciate anyone taking the time to help me, even if a little closer to a solution.
In func showOverlay(_ sender: UIButton) {...} you are creating a local variable "overlayView":
let overlayView = UIView(frame: ...)
You then add that as a subview to view. All that is fine, except you do not keep a reference to "overlayView" .. the view remains but you have no reference to it.
Add a class-level variable, outside of any function blocks:
var overlayView: UIView!
Then, inside func showOverlay(_ sender: UIButton) {...}, instead of let overlayView = just assign it to the existing variable:
overlayView = UIView(frame: ...)
When you're ready to remove it:
func hideOverlay(_ sender: UIButton) {
overlayView.removeFromSuperview()
}
and you're done :)
Try the viewWithTag method described in a similar thread here:
Swift addsubview and remove it

Swift 3 add remove subview and its content dynamically

I am writing my first Swift app for quiz. Each question has random way to render on screen as below screenshot.
I am programming app without story board ie. programmatically. I want to create simple pagination flow for each question within single viewcontroller without using Collocationview, Tableview or navigation.
What I did so far? I have simple viewcontroller with UIView() added as subview. I am adding question components dynamically. Now once user click on continue I wanted remove subview and add new subview with new question. I am able to remove subview but contents on subview seems to be still there as I can see its overwriting.
To get more clarification please view my code.
import UIKit
class QuizController: UIViewController {
let subView = UIView()
var currentQuestion:Int = 1;
let questions = ["This is question 1", "Hello to question 2", "Question 3"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
setup_layout()
}
func setup_layout(){
let closeBtn = UIButton(frame: CGRect(x: 5, y: 10, width: 200, height: 50))
closeBtn.backgroundColor = UIColor.red
closeBtn.setTitle("Close", for: .normal)
closeBtn.addTarget(self, action: #selector(close), for: .touchUpInside)
view.addSubview(closeBtn)
//dynamic view
create_subview()
}
func nextQuestion(){
print("Show next")
if let viewWithTag = self.view.viewWithTag(currentQuestion) {
viewWithTag.removeFromSuperview()
currentQuestion += 1;
create_subview()
} else {
print("No!")
}
}
func create_subview(){
let heightOfView = view.frame.size.height
let widthOfView = view.frame.size.width
subView.tag = currentQuestion
subView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.2)
subView.frame = CGRect(x: 0, y: 60, width: self.view.frame.width, height: heightOfView - 60)
self.view.addSubview(subView)
let txtLabel1 = UILabel(frame: CGRect(x: 35, y: 120, width: widthOfView , height: 20))
txtLabel1.text = questions[currentQuestion-1]
txtLabel1.font = txtLabel1.font.withSize(12)
subView.addSubview(txtLabel1)
let nextBtn = UIButton(frame: CGRect(x: 5, y: 300, width: 200, height: 50))
nextBtn.backgroundColor = UIColor.red
nextBtn.setTitle("Continue", for: .normal)
nextBtn.addTarget(self, action: #selector(nextQuestion), for: .touchUpInside)
subView.addSubview(nextBtn)
}
func close(){
self.dismiss(animated: true, completion: nil)
}
}
And this is what I see which I click continue.
NOTE: Initially thought using Collocation or Table view will be more appropriate as I can set to scroll horizontally for each question and fetch questions using REST API and place to each cell. But I want to present next screen to user only once then click on continue. I guess with collectionview user can move to next screen on swipe.
Just found the answer. I assumed removing subview will also remove all components on subview by itself ie. UILable and UIButton in my case.
I have to remove them separately.
for subview in self.subView.subviews {
subview.removeFromSuperview()
}
Now i can add tag to components and remove like this:
for subview in self.subView.subviews {
if (subview.tag == 1) {
subview.removeFromSuperview()
}
}
Why are you removing superviews and adding again and again??
Simply change UILabel.text :)

Custom navigation bar items improperly placed

I have a custom navigation bar subclass:
class ProfileNavigationBar: UINavigationBar {
var titleLabel: UILabel
var backButton: UIBarButtonItem
var friendsButton: FriendsButton?
required init?(coder: NSCoder) {
titleLabel = UILabel(frame: CGRect(x: 0, y: 40, width: 320, height: 40))
backButton = UIBarButtonItem.backButton(nil, action: nil)
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
super.init(coder: coder)
}
override func awakeFromNib() {
super.awakeFromNib()
let item = UINavigationItem()
item.titleView = titleLabel
item.leftBarButtonItem = backButton
item.hidesBackButton = true
let friendsItem = UIBarButtonItem(customView: friendsButton!)
item.rightBarButtonItems = [friendsItem]
pushItem(item, animated: false)
}
}
where the FriendsButton resizes itself when it's state property is changed.
Problem is that when the view is first loaded, it appears like this, with the back button and the FriendsButton right at the edge of the nav bar: (.loading state)
However, when I change the FriendsButton state to .add, it appears normally like this:
How can I fix this?
Here is the implementation of FriendsButton:
class FriendsButton: UIView {
var state: FriendsButtonState {
didSet {
style(selected: state)
}
}
var title: String = "" {
didSet {
set(title: title)
}
}
var font = UIFont.boldSystemFont(ofSize: 11)
private var imageView: UIImageView!
private var button: UIButton!
var loading: UIActivityIndicatorView!
init(frame: CGRect, state: FriendsButtonState = .loading) {
self.state = state
super.init(frame: frame)
backgroundColor = .yellow
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
imageView = UIImageView(frame: CGRect(x: plusYValue*2, y: plusYValue, width: plusSize, height: plusSize))
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button = UIButton(frame: CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height))
addSubview(button)
loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
addSubview(loading)
style(selected: state)
updateSize()
}
func addTarget(object: Any, selector: Selector) {
button.addTarget(object, action: selector, for: .touchUpInside)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
loading.startAnimating()
loading.isHidden = state != .loading
isHidden = false
switch state {
case .friends:
backgroundColor = .black
button.setTitleColor(.white, for: .normal)
imageView.image = #imageLiteral(resourceName: "friends-tick")
title = "Friends"
// ... + all other cases
}
self.updateSize()
}
private func configureBorder(state: FriendsButtonState) {
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = state == .loading ? 0 : 1
layer.cornerRadius = 5
}
private func set(title: String) {
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button.titleLabel?.font = font
button.setTitle(title, for: .normal)
button.frame = CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height)
self.updateSize()
}
private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
return
}
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}
EDIT: I have tried setting the button to the .add state initially but it would still appear at the very right of the nav bar until it was changed to the other state. It seems that the first state of the button always make the nav bar to shift all its children to the edge of the frame until it is updated.
EDIT: I wasn't able to reproduce the problem on another project by copying the relevant code, but this is the specific problem I am having (shown in the image below). The gap between the edge of the navigation bar and the back button is not maintained when first navigating to the view (I managed to get a screenshot midway through the navigation push animation). My question is now, what could be causing this?
You'll have to stop the activity indicator, otherwise it won't hide itself:
private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
if (state == .loading) {
loading.startAnimating()
} else {
loading.stopAnimating()
}
loading.isHidden = state != .loading
Btw: You could also skip loading.isHidden = state != .loading if you configure the UIActivityIndicatorView as to hide itself when its stopped:
init(frame: CGRect, state: FriendsButtonState = .loading) {
// ...
loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
loading.hidesWhenStopped = true
addSubview(loading)
// ...
}
To lay out the right navigation bar button correctly, you have to modify FriendsButton.updateSize: When in state .loading - at least for the first time - you also have to update the frame.
private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
// do not return here
}
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}
I assume the same for the left button, but unfortunalty the your code does not compile here (get an error in the init? method when calling backButton = UIBarButtonItem.backButton(nil, action: nil), because there is no static member backButton on UIBarButtonItem
Now, it works on my machine:
Just after start of the app:
After state change to .friends
State changed back again to .loading
Everything is well aligned, no changes etc.
If this does not hold true for your project, than there might be other aspects that you didn't publish with your code.
You should update the frames of the subviews in layoutSubviews(), so you should override this method. The layoutSubviews() method is called whenever the frame changes and when the layout is flagged as being 'dirty' (by calling setNeedsLayout() you can achieve this).
It looks like you want to set the FriendsButtonState of the friendsButton in the init. Change:
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
to
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24), state:.add)

Selector method of UIButton not called during animation

I have dynamically created buttons on a dynamic view and later I add that dynamic view to main view.
Everything is working well except that the selector method of UIButton is not called.
var baseView:UIView?
override func viewDidLoad() {
super.viewDidLoad()
randomizeButtons()}
func randomizeButtons(){
baseView = UIView(frame:CGRectMake(view.bounds.origin.x + 10, view.bounds.origin.y + 50, view.bounds.size.width, view.bounds.size.height-20))
let viewWidth = baseView.bounds.size.width;
let viewHeight = baseView.bounds.size.height;
baseView.userInteractionEnabled = true
let i = GlobalArrayofUsers.count
var loopCount = 0
while loopCount < i{
let userBaseView = UIView(frame: CGRectMake(abs(CGFloat(arc4random()) % viewWidth - 90) , abs(CGFloat(arc4random()) % viewHeight - 120), 90, 90))
print(userBaseView.frame)
userBaseView.backgroundColor = UIColor.redColor()
userBaseView.userInteractionEnabled = true
userBaseView.layer.cornerRadius = 45
userBaseView.clipsToBounds = true
let button = UIButton(frame: userBaseView.bounds)
button.backgroundColor = UIColor.greenColor()
button.showsTouchWhenHighlighted = true
button.addTarget(self, action: #selector(ViewController.handleTapEventofBtn(_:)), forControlEvents: .TouchUpInside)
button.setTitle("hello", forState: .Normal)
button.userInteractionEnabled = true
userBaseView.addSubview(button)
baseView.addSubview(userBaseView)
print("button frame is\(button.frame)")
baseView.bringSubviewToFront(userBaseView)
loopCount += 1
}
}
baseView.subviews.forEach { (users) in
UIView.animateWithDuration(1, delay: 0, options: [.Autoreverse,.Repeat], animations: {
users.center.y += 10
}, completion: nil)
}
view.insertSubview(baseView, atIndex: view.subviews.count)
}
func handleTapEventofBtn(sender: UIButton!) {
// handling code
}
Any idea why my selector method is not called? It is due to animation. How can i handle it.
SOLUTION: Allow userinteraction in UIAnimationOptions
The problem is that you are trying to click an object that is being animated. From the docs:
During an animation, user interactions are temporarily disabled for
the views being animated. (Prior to iOS 5, user interactions are
disabled for the entire application.)
But worry not, the solution is very easy, just call your animation with the option .AllowUserInteraction. For example (with your code):
UIView.animateWithDuration(1, delay: 0, options: [.Autoreverse,.Repeat,.AllowUserInteraction], animations: {
users.center.y += 10
}, completion: nil)
Have you tried this way:
for _ in 0...5{
// generate new view
let userBaseView = UIView(frame: CGRectMake(abs(CGFloat(arc4random()) % viewWidth - 90) , abs(CGFloat(arc4random()) % viewHeight - 120), 90, 90))
userBaseView.backgroundColor = UIColor.redColor()
// add button to view
let button = UIButton(frame: userBaseView.bounds)
button.backgroundColor = UIColor.yellowColor()
button.showsTouchWhenHighlighted = true
button.addTarget(self, action: #selector(self.handleTapEventofBtn(_:)), forControlEvents: .TouchUpInside)
button.setTitle("hello", forState: .Normal)
userBaseView.addSubview(button)
}
self.view.addSubview(userBaseView)
All you need is to create userBaseView before cycle, then create buttons in cycle and add them to userBaseView, after that just add userBaseView to self.view or where you need to add it. In your example you create userBaseView in every iteration of the loop.
I think the problem could be here:
userBaseView.addSubview(button)
// add new view containing button to self.view
self.view.addSubview(userBaseView)
}
userBaseView.addSubview(button)
baseView.addSubview(userBaseView)
First you add userBaseView to self.view in the loop:
// add new view containing button to self.view
self.view.addSubview(userBaseView)
then add it to baseView:
baseView.addSubview(userBaseView)
Can you post how it looks like in IB?
The action has a parameter so the selector signature is actually takeActionBtn:
(note the colon at the end).
You need to change that or the button will try to call a version of the function with no parameter which doesn't exist.
button.addTarget(self, action: "button:",forControlEvents: UIControlEvents.TouchUpInside)
func button(sender: UIButton!) {
// handling code
print("1")
}
// hi. your problem is in the selector line. try this:
for _ in 0...5 {
// generate new view
let userBaseView = UIView(frame: CGRectMake(abs(CGFloat(arc4random()) % self.view.frame.size.width - 90) , abs(CGFloat(arc4random()) % self.view.frame.size.height - 120), 90, 90))
userBaseView.backgroundColor = UIColor.redColor()
// add button to view
let button = UIButton(frame: userBaseView.bounds)
button.backgroundColor = UIColor.yellowColor()
button.showsTouchWhenHighlighted = true
button.addTarget(self, action: "buttonAction", forControlEvents: UIControlEvents.TouchUpInside)
button.setTitle("hello", forState: .Normal)
userBaseView.addSubview(button)
self.view.addSubview(userBaseView)
}
// tested with xcode 7.2
func buttonAction() {
print("working")
}

Resources