1

I have a ScrollView. You can scroll but the buttons don't allow you to press them(when you press them they don't do anything). Can you help fix this? Here is my current code:

PS: I'm checking this regularly so if you have a question I'll answer.

class ViewController: UIViewController {





    @IBOutlet weak var categoryScrollView: UIScrollView!




    var categoryArr = ["Button1","Button2","Button3","Button4","Button5", "Button 6", "Button 7", "Button 8", "Button 9", "Button 10", "Button 11", "Button 12"]
    var buttonColors = [UIColor.greenColor(), UIColor.blueColor(), UIColor.blackColor(), UIColor.cyanColor(), UIColor.magentaColor(), UIColor.greenColor(), UIColor.blueColor(), UIColor.blackColor(), UIColor.cyanColor(), UIColor.magentaColor(), UIColor.blackColor(), UIColor.brownColor()]
    var buttonImages = [UIImage(named: "One"), UIImage(named: "Two"), UIImage(named: "Three"), UIImage(named: "PlayButtonImage"), UIImage(named: "Triangle"), UIImage(named: "PlayButtonImage"), UIImage(named: "Triangle"), UIImage(named: "PlayButtonImage"), UIImage(named: "Triangle"), UIImage(named: "PlayButtonImage"), UIImage(named: "Triangle"), UIImage(named: "PlayButtonImage")]


    let kPadding:CGFloat = 20


    override func viewDidLoad() {
        super.viewDidLoad()



        let buttonSize = CGSizeMake(categoryScrollView.bounds.size.width/2, categoryScrollView.bounds.size.height/2)//hal

        let scrollingView = ImageButtonsView(buttonSize, buttonCount: 12)
        categoryScrollView.contentSize = scrollingView.frame.size
        categoryScrollView.addSubview(scrollingView)
        categoryScrollView.showsVerticalScrollIndicator = false
        categoryScrollView.delegate = self
        categoryScrollView.pagingEnabled = true
        categoryScrollView.indicatorStyle = .Default
        categoryScrollView.contentOffset = CGPointMake(0, 0)
        categoryScrollView.delaysContentTouches = false
        categoryScrollView.userInteractionEnabled = true;
        categoryScrollView.exclusiveTouch = true;
        categoryScrollView.canCancelContentTouches = true;
        //categoryScrollView.clipsToBounds = true

    }


    func ImageButtonsView(buttonSize:CGSize, buttonCount:Int) -> UIView {




        let buttonView = UIView()
        buttonView.frame.origin = CGPointMake(50,142)
        let padding = CGSizeMake(kPadding, kPadding)
        buttonView.frame.size.width = (buttonSize.width + padding.width) * CGFloat(buttonCount)
        var buttonPosition = CGPointMake(0, padding.height)
        let buttonIncrement = buttonSize.width + padding.width
        for i in 0...(buttonCount - 1)  {


            let button = UIButton(type: .Custom)

            buttonView.userInteractionEnabled = true

            button.frame.size = buttonSize
            button.frame.origin = buttonPosition
            buttonPosition.x = buttonPosition.x + buttonIncrement
            button.setTitle(categoryArr[i], forState: UIControlState.Normal)
            let buttonImagesOne = buttonImages[i]
            button.setImage(buttonImagesOne, forState: .Normal)
            button.layer.cornerRadius = 30
            button.addTarget(self, action: "pressed:", forControlEvents: UIControlEvents.TouchUpInside)
            buttonView.addSubview(button)









        }
        //buttonView.backgroundColor = UIColor.redColor()
        categoryScrollView.bringSubviewToFront(buttonView)


        return buttonView

    }


}




extension ViewController:UIScrollViewDelegate{
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {





        let index = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        print(index)
    }



    func pressed(/*sender: UIButton!*/) {

        let vc = UIViewController(nibName: "GridViewController", bundle: nil)
        self.presentViewController(vc, animated: true, completion:nil)

        //viewController.hidden = true






    }

}

BalestraPatrick
  • 9,944
  • 4
  • 30
  • 43
Nick G
  • 45
  • 2
  • 8

4 Answers4

1

Originally here, I thought the line

button.addTarget(self, action: "pressed:", forControlEvents: UIControlEvents.TouchUpInside)

should have said "pressed" without a ":". But that turned out to be a misunderstanding on my part, sorry. It should be "pressed:".

Instead, this may be related to Protocol extension and addTarget is crashing with NSInvalidArgumentException which is also very confusing.

Community
  • 1
  • 1
emrys57
  • 6,679
  • 3
  • 39
  • 49
  • With doing that (and what EmilioPalaez said), the buttons still don't do anything when pressed, as I said before, you can scroll but you can't click on the buttons. – Nick G Feb 06 '16 at 17:04
  • If you put a logging statement in the pressed() function, does it log? Is the function reached? – emrys57 Feb 06 '16 at 17:06
  • Can you give me an example of what you're talking about? – Nick G Feb 06 '16 at 17:08
  • `print("pressed!")`. Also, I think you need a parameter in this function. see edited answer. – emrys57 Feb 06 '16 at 17:12
  • After using your suggestions I changed the sender in the pressed function to "UIButton", then when that didn't work I changed it to "AnyObject", in which also didn't work. But I did also add the "print('pressed')" line, when attempting to click on the button, which was never shown, insinuating that the function may not have been reached. – Nick G Feb 06 '16 at 17:18
  • Sorry, no more suggestions, then. But I do think the modified code in the answer is right. Good Luck! – emrys57 Feb 06 '16 at 17:28
  • I'll continue to play with the code and see if I can make it work, which if I do I'll post here for other users, but thank you a ton for all your help! – Nick G Feb 06 '16 at 17:32
1

It turned out my scrollview's layout was set to "Autoresizing Mask" instead of "Inferred (Constraints)". Although my layout looked good, my buttons were actually outside the bounds of the scrollview and therefore couldn't be clicked!

Inferred ("Constraints") option in Storyboard

0

Have you tried adding a UITapGestureRecognizer to your button? You could try something like this:

let myTap = UITapGestureRecognizer(target: self, action: Selector("handleButtonTap:"))
myTap.delegate = self
//**Make your class inherit from UIGestureRecognizerDelegate otherwise an error will be thrown**
myButton.addGestureRecognizer(myTap)

Then write a function (the name of the function should be what you put in the action field above. So in this case the function would be called handleButtonTap. Here is the code:

func handleButtonTap() {
// Handle what happens when the button is tapped.
}

I hope I was able to help :).

Harish
  • 1,374
  • 17
  • 39
0

This is my approach (Swift 2 / xCode 7.2.1): I have 2 View Controllers:

“VC1” with the scrollview Here I create the different views (instances of “VC2”) and add them to the scrollview:

    scrollView.addSubview(pageStep.view)
    addChildViewController(pageStep)

which I call page1, page2, page3 … Then you can access the "page1.btn1" and do something like this

page1.nextBtn.addTarget(self, action: "nextPage:", forControlEvents: .TouchUpInside)

func nextPage(sender: UIButton!) {
        let xPosition = (pageFraction + 1) * scrollSize
        scrollView.setContentOffset(CGPoint(x: xPosition, y: 0), animated: true)
}

“VC2” With the outlets (each page) (UIImage, Buttons etc.)

I hope it helps !

Marcos
  • 461
  • 6
  • 10