简体   繁体   English

以编程方式设置视图。 在UIView子类中添加了UIButton。 UIButton直观地显示它们被单击,但不响应选择器

[英]Set view programmatically. UIButtons added in UIView subclass. UIButtons visually show they are clicked but don't respond to selectors

Here is my code: 这是我的代码:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        [self setupSubviewsWithContentFrame:frame];

        self.backgroundColor = [UIColor colorWithRed:0.0f/255.0 green:0.0f/255.0 blue:0.0f/255.0 alpha:.75];
        self.opaque = NO;

    }
    return self;
}

- (void)setupSubviewsWithContentFrame:(CGRect)frameRect 
{    
    // Get and set needed information for views/layout

    NSMutableDictionary *punchButtonDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Add a Punch", @"title", nil];
    // Create the selector
    SEL punchSelector = @selector(showScanner);
    // Add selector to the dictionary
    [punchButtonDict setObject:NSStringFromSelector(punchSelector) forKey:@"selectorKey"];

    // Create dictionary for email button
    NSMutableDictionary *okButtonDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"OK!", @"title", nil];
    // Create the selector
    SEL okSelector = @selector(hideView);
    // Add selector to the dictionary
    [okButtonDict setObject:NSStringFromSelector(okSelector) forKey:@"selectorKey"];

    // Create an array of the button dictionaries 
    blackButtons = [NSArray arrayWithObjects:punchButtonDict, okButtonDict, nil];

    // Count how many buttons are on this screen
    NSUInteger itemCount = blackButtons.count;

    // Stretchable image for counter background (placed here so it can be used for height)
    UIImage* counterBg =[[UIImage imageNamed:@"CounterStretchableBackground.png"]stretchableImageWithLeftCapWidth:10.0 topCapHeight:0.0];

    // Create a start x and y point for the view holder (to center it)
    int xPoint = ((self.bounds.size.width - SUBVIEW_WIDTH)/2);
    int yPoint = (((self.bounds.size.height - STATUS_BAR_HEIGHT) - (counterBg.size.height + (PADDING*(itemCount - 1)) + BUTTON_HEIGHT*itemCount)) / 2);

    // Setup each subview

    // First View viewHolder
    UIView *viewHolder = [[UIView alloc] init];
    // Get the height for viewHolder
    int viewHolderHeight = (counterBg.size.height + (PADDING*2) + (BUTTON_HEIGHT*itemCount));
    // Set the frame for the first view
    viewHolder.frame = CGRectMake(xPoint, yPoint, SUBVIEW_WIDTH, viewHolderHeight);

    // Create view for counter 
    UIImageView* counterView = [[UIImageView alloc] initWithImage:counterBg];
    // Set the frame to center (with respect to other buttons)
    counterView.frame = CGRectMake(0, 0, SUBVIEW_WIDTH, counterBg.size.height);

    // Create numberCount label (subview of counterView)
    _numberCount = [[UILabel alloc] initWithFrame:CGRectMake(0, COUNTER_PADDING, SUBVIEW_WIDTH, (((counterBg.size.height  - COUNTER_PADDING)/2)))];
    // Set label background to clear
    _numberCount.backgroundColor = [UIColor clearColor];
    // Set text
    _numberCount.text = @"0";
    // Set font
    _numberCount.font = [UIFont fontWithName:@"Oswald" size:32.0];
    // Set font color
    _numberCount.textColor = [UIColor colorWithRed:255.0f/255.0 green:255.0f/255.0 blue:255.0f/255.0 alpha:.9];
    // Set alignment
    _numberCount.textAlignment = UITextAlignmentCenter;
    // Set shadow color
    _numberCount.shadowColor = [UIColor colorWithRed:0.0f/255.0 green:0.0f/255.0 blue:0.0f/255.0 alpha:1.0];
    // Set shadow offset
    _numberCount.shadowOffset = CGSizeMake(0.0, 1.0);

    // Create numberCount label (subview of counterView)
    UILabel *punchesLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, (((counterBg.size.height)/2) + PADDING*2), SUBVIEW_WIDTH, 13)];
    // Set label background to clear
    punchesLabel.backgroundColor = [UIColor clearColor];
    // Set text
    punchesLabel.text = @"Punches";
    // Set font
    punchesLabel.font = [UIFont fontWithName:@"PTSans-Bold" size:13.0];
    // Set font color
    punchesLabel.textColor = [UIColor colorWithRed:255.0f/255.0 green:255.0f/255.0 blue:255.0f/255.0 alpha:.9];
    // Set alignment
    punchesLabel.textAlignment = UITextAlignmentCenter;
    // Set shadow color
    punchesLabel.shadowColor = [UIColor colorWithRed:0.0f/255.0 green:0.0f/255.0 blue:0.0f/255.0 alpha:1.0];
    // Set shadow offset
    punchesLabel.shadowOffset = CGSizeMake(0.0, 1.0);

    // Create toGoLabel (subview of counterView)
    _toGoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, (((counterBg.size.height)/2) + PADDING*3 + punchesLabel.frame.size.height), SUBVIEW_WIDTH, 12)];
    // Set label background to clear
    _toGoLabel.backgroundColor = [UIColor clearColor];
    // Set text
    _toGoLabel.text = @"7 more to go!";
    // Set font
    _toGoLabel.font = [UIFont fontWithName:@"PTSans-Regular" size:11.0];
    // Set font color
    _toGoLabel.textColor = [UIColor colorWithRed:240.0f/255.0 green:240.0f/255.0 blue:240.0f/255.0 alpha:.9];
    // Set alignment
    _toGoLabel.textAlignment = UITextAlignmentCenter;
    // Set shadow color
    _toGoLabel.shadowColor = [UIColor colorWithRed:0.0f/255.0 green:0.0f/255.0 blue:0.0f/255.0 alpha:1.0];
    // Set shadow offset
    _toGoLabel.shadowOffset = CGSizeMake(0.0, 1.0);


    // Add views in proper order and location

    [self addSubview:viewHolder];

    [viewHolder addSubview:counterView];

    [counterView addSubview:_numberCount];

    [counterView addSubview:punchesLabel];

    [counterView addSubview:_toGoLabel];


    // First button y start point
    int buttonY = counterBg.size.height + PADDING;
    // Stretchable image for counter background (placed here so it can be used for height)
    UIImage* blackButton =[[UIImage imageNamed:@"UIButtonBlack.png"]stretchableImageWithLeftCapWidth:10.0 topCapHeight:0.0];

    // Iterate through each item
    for (NSUInteger i = 0 ; i < itemCount ; i++)
    {


        // Get the right data
        NSDictionary* data = [blackButtons objectAtIndex:i];
        // Return the title for this button
        NSString *buttonText = [data objectForKey:@"title"];

        SEL buttonSelector = NSSelectorFromString([data objectForKey:@"selectorKey"]);

        NSLog(@"%@", [data objectForKey:@"selectorKey"]);

        // Create button frame
        CGRect buttonFrame = CGRectMake(0, buttonY, SUBVIEW_WIDTH, BUTTON_HEIGHT);

        UIButton *newButton;

        UIImage *iconImage = [UIImage imageNamed:@"EmailIcon.png"];

        newButton = [self buttonWithTitle:buttonText target:self selector:buttonSelector frame:buttonFrame image:blackButton insertImage:iconImage];

        [self addSubview:newButton];

        buttonY += (PADDING + BUTTON_HEIGHT);

    }

//    for (UIView *view in self.subviews)
//
//    view.userInteractionEnabled=NO;


    [self setNeedsDisplay];

}

- (UIButton *)buttonWithTitle:(NSString *)title target:(id)target selector:(SEL)inSelector frame:(CGRect)frame image:(UIImage*)image insertImage:(UIImage*)insertImage
{
    // Create button
    UIButton *button = [[UIButton alloc] initWithFrame:frame];

    // Set button content alignment
    button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

    // Set button title
    [button setTitle:title forState:UIControlStateNormal & UIControlStateHighlighted & UIControlStateSelected];
    // Set button title color
    [button setTitleColor:[UIColor colorWithRed:255.0f/255.0 green:255.0f/255.0 blue:255.0f/255.0 alpha:1.0] forState:UIControlStateNormal & UIControlStateHighlighted & UIControlStateSelected];
    // Add the background image
    [button setBackgroundImage:image forState:UIControlStateNormal];
    // Add Events
    [button addTarget:target action:inSelector forControlEvents:UIControlEventTouchUpInside & UIControlEventTouchDown];
    // in case the parent view draws with a custom color or gradient, use a transparent color
    [button setBackgroundColor:[UIColor clearColor]];  
    // Set titleShadowColor this way (apparently, titleLabel.shadowcolor does not work)
    [button setTitleShadowColor:[UIColor colorWithRed:0.0f/255.0 green:0.0f/255.0 blue:0.0f/255.0 alpha:.75] forState:UIControlStateNormal & UIControlStateHighlighted & UIControlStateSelected];

    // Set button titleLabel properties  
    button.titleLabel.font = [UIFont fontWithName:@"PTSans-Bold" size:13.0];
    button.titleLabel.shadowOffset = CGSizeMake(1, 1);    

    // If there is an insertImage icon
    if(insertImage != nil) 
    {
        // padding between image and text
        int seperate = 6; 
        // Image and title frame (used to center text/image)
        int width = (button.titleLabel.frame.size.width + insertImage.size.width + seperate);
        int buttonWidth = button.frame.size.width;
        int xPadding = (buttonWidth - width)/2;
        int yPadding = (button.frame.size.height - insertImage.size.height)/2;

        // Create an image view for the image (standard icon is 12x13)
        UIImageView *insertImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xPadding, yPadding, insertImage.size.width, insertImage.size.height)];
        // add the insertImage to the view
        [insertImageView setImage:insertImage];
        // add the insertImageView to the button
        [button addSubview:insertImageView];
        // Add offset with title
        button.titleEdgeInsets = UIEdgeInsetsMake(BUTTON_VERTICAL_INSET, insertImage.size.width + seperate, 0, 0);
    }
    else 
    {
        // No image so no horizontal offset but PTSans font needs a 2 vertical offset
        button.titleEdgeInsets = UIEdgeInsetsMake(BUTTON_VERTICAL_INSET, 0, 0, 0);
    }
    return button;
}

This is how I set the view to it's view controller 这就是我将视图设置为其视图控制器的方式

rewardsView = [[RewardsView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view = rewardsView;

In your NSLog you should not check what selector string is stored in your data dictionary but if the SEL variable contains the correct selector. 在您的NSLog您不应检查数据字典中存储了哪些选择器字符串,而应检查SEL变量是否包含正确的选择器。

I strongly recommend simplifying the code. 我强烈建议简化代码。 The approach to store the parameters of the buttons in an array of dictionaries is quite error prone. 将按钮的参数存储在词典数组中的方法很容易出错。 You end up with way to many parameters. 您最终将获得许多参数。 Finding an error like yours (selector does not fire) becomes much more difficult than necessary. 找到像您这样的错误(选择器不会触发)变得比必要的困难得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM