Enabled UIButton not responding to touch events

Hi,


I'm a little confused here. I have a UIButton encased inside a MenuItemView, which is inside an ExerciseMenuView. The UIButton isn't outside the MenuItemView's frame, and userInteractionEnabled on the button is set to "true". Yet, I don't know why I can't touch the button.

Edit: I didn't use an XIB here. I had an XIB for my MenuItemView's superview, which worked for a while before something decided to mess up the app.


MenuItemView's code:

/
/
/
/
/
/
/
import UIKit
enum ActivityStatus {
    case NotThereYet
    case Next
    case Completed
}
class MenuItemView: UIView {
    var currentStatus : ActivityStatus = ActivityStatus.NotThereYet
    var starNum : Int = 1
     let button: UIButton! = UIButton()
    @IBOutlet var starImageView: UIImageView! {
        didSet {
       
            /
            let mainBundle = Bundle(for: MenuItemView.self)
            let starURL = mainBundle.path(forResource: "\(starNum)star", ofType: "png", inDirectory:"pictures")
            let starImage = UIImage(contentsOfFile: starURL!)
            starImageView!.image = starImage!
            button.bringSubview(toFront: button)
            /
            self.starImageView!.isHidden = true
            /
            self.starImageView!.contentMode = UIViewContentMode.scaleAspectFit
        }
    }/* Star image view. Defined in storyboard **/
    func buttonPressed() {
        (superview as! ExerciseMenuView).buttonPressed(sender: self)
    }
    init(frame: CGRect,_tag: Int)
    {
        super.init(frame: frame)
                tag = _tag;
                starImageView = UIImageView(frame: bounds)
                addSubview(starImageView!)
                addPlayButton()
    }
    func addPlayButton() /
    {
        /
        self.addSubview(button)
        /
        let mainBundle = Bundle(for: MenuItemView.self)
        let playURL = mainBundle.path(forResource: "play-button", ofType: "png", inDirectory:"pictures")
   
        let playImage = UIImage(contentsOfFile: playURL!)
        button.setBackgroundImage(playImage, for: UIControlState.normal)
        button.isUserInteractionEnabled = false
        /
        button.addTarget(self, action: #selector(MenuItemView.buttonPressed), for: UIControlEvents.touchUpInside)
        /
        button.translatesAutoresizingMaskIntoConstraints = true
        /
        let buttonOrigin = CGPoint(x:0, y:bounds.maxY)
        let buttonSize = CGSize(width: bounds.size.width, height: 128)
        button.frame = CGRect(origin: buttonOrigin, size: buttonSize)
        /
        button.contentMode = UIViewContentMode.scaleAspectFit
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
       addPlayButton()
    }
    override init(frame: CGRect)
    {
        super.init(frame: frame)
    }
    func setActivityStatus(newStatus : ActivityStatus) {
        self.isHidden = false
        currentStatus = newStatus
        switch newStatus {
        case .Next:
            button.isHidden = false
            button.isUserInteractionEnabled = true
        case .Completed:
            starImageView!.isHidden = false
            button.isUserInteractionEnabled = false
            button.isHidden = true
        default:
            button.isHidden = true
            starImageView!.isHidden = true
            break
       
        }
        /
        if (self.tag == 2)
        {
            print("setActivityStatus: Star image view superview is \(String(describing: starImageView?.superview))")
        }
    }
    /
    /
    /
    override func drawRect(rect: CGRect) {
        /
    }
    */
}


ExerciseMenuView's (MenuItemView superview) code:

import UIKit
import QuartzCore
@IBDesignable @objc class ExerciseMenuView: UIView {
    var viewController : ExerciseMenuViewController!
    var wordFamilyIndex : Int = 0
     var activityIndex : Int = 0
    @IBOutlet weak var backgroundImageView: UIImageView!
    @IBAction func buttonPressed(sender: MenuItemView) {
       
        viewController.activityButtonPressed(sender.button)
    }
    override func awakeFromNib()
    {
        /
        if (tag == 2 || tag == 5 || tag == 7) { /
            var frame : CGRect
            var itemTag = 0
            if (tag == 2)
            {
                frame = CGRect(x: 764, y: 543, width: 211, height: 128)
                itemTag = 2
            }
            else if (tag == 7)
            {
                frame = CGRect(x: 711, y: 83, width: 211, height: 128)
                itemTag = 40
            }
            else
            {
                frame = CGRect(x:764,y:543,width:211,height:128)
                itemTag = 0
            }
            let menuItemView = MenuItemView(frame: frame)
            menuItemView.tag = itemTag
            menuItemView.starImageView = UIImageView(frame: menuItemView.bounds)
            menuItemView.addSubview(menuItemView.starImageView!)
            menuItemView.addPlayButton()
            self.addSubview(menuItemView)
        }
    }
    override func layoutSubviews()
    {
        super.layoutSubviews()
        /
        /* let backgroundImageView = UIImageView.init(image: backgroundImage)
        backgroundImageView.frame = self.bounds
        self.addSubview(backgroundImageView)
    self.sendSubviewToBack(backgroundImageView)**/
        /
        let widthScaleFactor = self.bounds.width / self.frame.width
        let heightScaleFactor = self.bounds.height / self.frame.height
        self.transform = CGAffineTransform(scaleX: widthScaleFactor, y: heightScaleFactor)
       
    }
    /* Updates each menu item view to reflect the user's progress in the current level **/
    func update()
    {
        let placeTag = wordFamilyIndex * 10 + activityIndex
        let menuItemViews = subviews.flatMap { $0 as? MenuItemView }
        for itemView in menuItemViews{
            let itemTag = itemView.tag
            var checkVisible = true
            if placeTag > itemTag {
                itemView.setActivityStatus(newStatus: ActivityStatus.Completed)
            }
            else if placeTag == itemTag {
                itemView.setActivityStatus(newStatus: ActivityStatus.Next)
            }
            else
            {
                checkVisible = false
                itemView.setActivityStatus(newStatus: ActivityStatus.NotThereYet)
            }
            if (checkVisible)
            {
                /
                let isInBounds = self.bounds.contains(itemView.frame)
                assert(isInBounds, "View \(itemTag) not in bounds.")
                let isZeroWidth = itemView.frame.size.width == 0
                assert (!isZeroWidth, "Width of view \(itemTag) is zero")
                let isZeroHeight = itemView.frame.size.height == 0
                assert(!isZeroHeight, "Height of view \(itemTag) is zero")
                let isHidden = itemView.isHidden
                assert (!isHidden, "Item view \(itemTag) is hidden")
                let isObscured = false /
                assert (!isObscured, "Item view \(itemTag) is obscured")
            }
        }
    }
}


ExerciseMenuViewController's code (where the "problem" MenuItemView is created):


/
/
/
/
/
/
/
#import "ExerciseMenuViewController.h"
#import "LevelObject.h"
#import "WordBuildingExerciseViewController.h"
#import "Reading_Expressway-Swift.h"
#import "TextCell.h"
#import "OtherTableViewCell.h"
#import "PlaceEntity+CoreDataProperties.h"
#define ChildKey @"child"
#define SectionKey @"section"
#define WordFamilyObjKey @"wordObject"
@interface ExerciseMenuViewController ()
@end
@implementation ExerciseMenuViewController
{
    XMLDataObject *dataObject;
    PlaceEntity *entity;
    NSArray *menuViews;
    ExerciseMenuView *levelView; /
}
@synthesize elements;
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    
    }
    return self;
}
-(void)viewDidLoad
{
    NSInteger level = [LevelObject currentLevel] + 1;
    /
    if (level == 1)
    {
        /
        levelView = [[ExerciseMenuView alloc] initWithFrame:self.view.frame];
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"level1homepic.png"]];
        backgroundView.frame = self.view.frame;
        levelView.backgroundImageView = backgroundView;
        [levelView addSubview:backgroundView];
        CGRect view0frame = CGRectMake(320, 491, 211, 128);
        MenuItemView *view0 = [[MenuItemView alloc] init];
        view0.frame = view0frame;
        [view0 addPlayButton];
        view0.tag = 0;
        [levelView addSubview:view0];
    }
    else {
    NSString *nibName = [NSString stringWithFormat:@"%i",level];
    NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
    levelView = [nibViews firstObject];
    [levelView setFrame:self.view.bounds];
    [self setMenuView:levelView];

    }
    [self.view addSubview:levelView];
    [levelView setViewController:self];
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    /
    entity = [[UserEntity sharedEntity] placeEntityForLevel:[LevelObject currentLevel]];
    elements = [self.element elementChildren];
    NSAssert([[elements.firstObject elementName] isEqualToString:@"wordFamily"], @"Expected word families.");
    /
    levelView.wordFamilyIndex = entity.familyNum;
    levelView.activityIndex = entity.activityNum;
    levelView.viewController = self;
    [levelView update];
    }
-(IBAction)goBack:(id)sender {
[(AppViewController *)self.presentingViewController setElement:[self.element parentObject]];
[self.navigationController popViewControllerAnimated:false];
}
-(IBAction)activityButtonPressed:(id)sender
{
    NSMutableArray *segues = [[NSMutableArray alloc] init];
    ElementObject *wordFamily = [self.elements objectAtIndex:entity.familyNum]; /
    ElementObject *activity; /
    if (wordFamily.elementChildren.count > 0)
    {
        activity = [wordFamily.elementChildren objectAtIndex:entity.activityNum];
    }
    else {
        activity = wordFamily;
    }
    [sender setElementObject:activity];
    if (![activity.elementName isEqualToString:@"storyRhyme"]) {
        [segues addObject:@"WordBuildingSegue"];
        ElementObject *currentWordFamily = wordFamily;
        NSString *wordFamilyName = [currentWordFamily.attributeDictionary valueForKey:@"name"];
        if ([entity level] > 0 || [wordFamilyName isEqualToString:@"at"]) {
            [segues addObjectsFromArray:@[@"WordBuildingSegue",@"SentenceBuildingSegue"]];
             }
        else
        {
            /
       
            [segues addObject:@"SentenceBuildingSegue"];
        }
        }
        else
        {
            [segues addObject:@"StoryRhymeSegue"];
        }
    NSString *segueIdentifier = [segues objectAtIndex:entity.activityNum];
    [self performSegueWithIdentifier:segueIdentifier sender:sender];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    NSLog(@"Exercise menu view received memory warning");
    /
}
@end

Replies

Go back to IB, delete the wired up connection for that button, then redo, option-clean the build folder and try again.

Well, this line looks wrong:


     let button: UIButton! = UIButton()


According to the UIButton documentation, you're supposed to specify the button type when you create it, so you need something like:


     let button: UIButton! = UIButton(type: .system) // or another type