对于以编程方式创建的 UIButton,有时不会触发按钮单击事件

Posted

技术标签:

【中文标题】对于以编程方式创建的 UIButton,有时不会触发按钮单击事件【英文标题】:Button click event not firing sometimes for programmatically created UIButton 【发布时间】:2015-11-17 00:55:24 【问题描述】:

我从情节提要中添加了UIScrollView,在该滚动视图中,我还有另一个UIView作为容器视图。在UIScrollView 后面我也有一个UIImageView 作为兄弟姐妹。这是我的视图层次结构。

现在我以编程方式将视图添加到此容器视图中。

-(void)setUI
   
      int i;
      for ( i=0; i<[array count]; i++) 

      NSLog(@"Object at index %i  %@",i,[array objectAtIndex:i]);

      UIView *view=[self GetAlertView:i];

    [self.contentView addSubview:view];
    float sizeOfContent = 0;

    if (notY+viewParent.frame.size.height>self.contentView.frame.size.height) 
        CGRect frame=self.contentView.frame;
        frame.size.height=notY;
        self.contentView.frame=frame;
    



    self.mainScroll.contentSize = self.contentView.frame.size;



这就是我生成视图的方式。

-(UIView *)GetAlertView :(int)index
     
       viewParent=[[UIView alloc] initWithFrame:CGRectMake(10, notY,     self.view.frame.size.width-20, 100)];
[viewParent setBackgroundColor:[UIColor clearColor]];
[viewParent setUserInteractionEnabled:YES];


UIImageView *backImage=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, viewParent.frame.size.width, viewParent.frame.size.height)];
[backImage setImage:[UIImage imageNamed:@"AlertBack"]];


//-------TITLE LABEL--------------

UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(20, 20, viewParent.frame.size.width-60, 30)];

[lblTitle setText:[[[array objectAtIndex:index] objectForKey:@"Info"] valueForKey:@"Headline"]];
[lblTitle setFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:15]];
[lblTitle setTextAlignment:NSTextAlignmentLeft];
[lblTitle setTextColor:[UIColor whiteColor]];

//-------ICON IMAGE------------

UIImageView *imgIco=[[UIImageView alloc] initWithFrame:CGRectMake(lblTitle.frame.origin.x+lblTitle.frame.size.width, 20, 30, 30)];

NSString *imgUrl=[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Resource"] valueForKey:@"Uri"];
if([[array objectAtIndex:index] valueForKey:@"Realimg"]!=nil)

    [imgIco setImage:[[array objectAtIndex:index] valueForKey:@"Realimg"]];

else

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        NSURL *imageURL = [NSURL URLWithString:imgUrl];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *image = [UIImage imageWithData:imageData];
        dispatch_async(dispatch_get_main_queue(), ^
            if(image!=nil)
                @try 
                    NSMutableDictionary *objectDict=[[NSMutableDictionary alloc] initWithDictionary:[[array objectAtIndex:index] mutableCopy]];
                    [objectDict setObject:image forKey:@"Realimg"];
                    [array replaceObjectAtIndex:index withObject:objectDict];

                
                @catch (NSException *exception) 

                
                @finally 

                

            

            [imgIco setImage:image];

        );
    );




UILabel *lblMessage=[[UILabel alloc] initWithFrame:CGRectMake(20, lblTitle.frame.origin.y+lblTitle.frame.size.height+10, viewParent.frame.size.width-40, 10)];
[lblMessage setUserInteractionEnabled:NO];

[lblMessage setNumberOfLines:0];
CGSize maximumLabelSize = CGSizeMake(viewParent.frame.size.width-40, FLT_MAX);
NSString *strDescript=[[[array objectAtIndex:index] objectForKey:@"Info"]valueForKey:@"Description"];


[lblMessage setText:strDescript];
[lblMessage setFont:[UIFont fontWithName:@"HelveticaNeue" size:14]];

CGSize expectedLabelSize = [strDescript sizeWithFont:lblMessage.font constrainedToSize:maximumLabelSize lineBreakMode:lblMessage.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = lblMessage.frame;
newFrame.size.height = expectedLabelSize.height;
lblMessage.frame = newFrame;
if (lblMessage.frame.size.height>10) 
    float extendedH=lblMessage.frame.size.height-10;


    CGRect newFrameMsg = viewParent.frame;
    newFrameMsg.size.height = viewParent.frame.size.height+extendedH;
    viewParent.frame = newFrameMsg;

    CGRect newImgFrame=backImage.frame;
    newImgFrame.size.height=backImage.frame.size.height+extendedH;
    backImage.frame=newImgFrame;



[lblMessage setTextColor:[UIColor whiteColor]];

NSLog(@"Circle %lu",[[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Circle"] count]);
int circleCount=[[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Circle"] count];

NSLog(@"Geocode %@",[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Geocode"]);
NSString *strGeoCod=[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Geocode"];

NSLog(@"Polygon %lu",[[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Polygon"] count]);
int polygonCount=[[[[[array objectAtIndex:index] objectForKey:@"Info"] objectForKey:@"Area"] objectForKey:@"Polygon"] count];

UIImageView *imgEvac;
UIButton *btnEvac;


if (circleCount!=0 || [strGeoCod length]!=0 || polygonCount!=0) 
    //----------EVACUATE IMAGE---------------
    imgEvac=[[UIImageView alloc] initWithFrame:CGRectMake(20, lblMessage.frame.origin.y+lblMessage.frame.size.height+5, 20, 30)];
    [imgEvac setUserInteractionEnabled:NO];
    imgEvac.animationImages=[NSArray arrayWithObjects:[UIImage imageNamed:@"Evac1"],
                             [UIImage imageNamed:@"Evac2"],
                             [UIImage imageNamed:@"Evac3"],
                             [UIImage imageNamed:@"Evac4"],
                             [UIImage imageNamed:@"Evac5"],
                             [UIImage imageNamed:@"Evac6"],
                             [UIImage imageNamed:@"Evac7"],
                             [UIImage imageNamed:@"Evac8"],
                             [UIImage imageNamed:@"Evac9"],
                             [UIImage imageNamed:@"Evac10"],
                             [UIImage imageNamed:@"Evac11"],
                             [UIImage imageNamed:@"Evac12"],
                             [UIImage imageNamed:@"Evac13"],
                             [UIImage imageNamed:@"Evac14"],nil];
    imgEvac.animationDuration = 1.0f;
    imgEvac.animationRepeatCount = 0;
    [imgEvac startAnimating];



    //----------EVACUATE BUTTON-------------
    btnEvac=[UIButton buttonWithType:UIButtonTypeCustom] ;
    [btnEvac setTitle:@"Evacuate" forState:UIControlStateNormal];
    [btnEvac setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
    [btnEvac addTarget:self action:@selector(EvacuateClick:) forControlEvents:UIControlEventTouchUpInside];

    btnEvac.frame=CGRectMake(imgEvac.frame.origin.x+imgEvac.frame.size.width+5, lblMessage.frame.origin.y+lblMessage.frame.size.height+5, 75, 30);






    intlbldateX=btnEvac.frame.origin.x+btnEvac.frame.size.width;

else

    intlbldateX=20;






//----------DATE LABEL------------------
UILabel *lblDate=[[UILabel alloc] initWithFrame:CGRectMake(intlbldateX, lblMessage.frame.origin.y+lblMessage.frame.size.height+5, viewParent.frame.size.width-(intlbldateX+10), 30)];
[lblDate setUserInteractionEnabled:NO];
[lblDate setBackgroundColor:[UIColor redColor]];
[lblDate setText:[[array objectAtIndex:index]valueForKey:@"Sent"]];
[lblDate setFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:15]];
[lblDate setTextAlignment:NSTextAlignmentRight];
[lblDate setTextColor:[UIColor whiteColor]];

CGRect newFrame2=viewParent.frame;
newFrame2.size.height=viewParent.frame.size.height+10;
viewParent.frame=newFrame2;

CGRect newImgFrame2=backImage.frame;
newImgFrame2.size.height=backImage.frame.size.height+10;
backImage.frame=newImgFrame2;

//---------垂直线--------------

UIView *vwVerticle=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, viewParent.frame.size.height)];
[vwVerticle setUserInteractionEnabled:NO];
[vwVerticle setBackgroundColor:[self colorWithHexString:[[[[[array objectAtIndex:index]objectForKey:@"Info"] objectForKey:@"Resource"] valueForKey:@"ColorCode"] stringByReplacingOccurrencesOfString:@"#" withString:@""]]];

[viewParent addSubview:backImage];
[viewParent addSubview:lblTitle];
[viewParent addSubview:imgIco];
[viewParent addSubview:lblMessage];
[viewParent addSubview:imgEvac];

[viewParent addSubview:lblDate];
[viewParent addSubview:vwVerticle];
[viewParent addSubview:btnEvac];


notY=viewParent.frame.origin.y+viewParent.frame.size.height+20;


return viewParent;

但我的问题是这个btnEvac 不可点击。但有时我只能点击一次。这是我的按钮点击事件。

-(IBAction)EvacuateClick :(UIButton *)sender
  
     NSLog(@"Evacuate clicked");
  

有时这是第一次触发。之后什么也没有发生。我不知道是什么原因。我也将用户交互启用 = YES 设置为我的滚动视图和容器视图。但不是启动图像视图。我希望我也不想设置。请帮帮我。

谢谢

这就是我将更多视图加载到底部的方式

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
float bottomEdge = self.mainScroll.contentOffset.y + self.mainScroll.frame.size.height;
if (bottomEdge >= self.mainScroll.contentSize.height) 
    // we are at the end

    //[self performSelectorInBackground:@selector(callscrol) withObject:nil];
    [self callscrol];

-(void)callscrol

if(!loading&& !resNull)

    float offs = (self.mainScroll.contentOffset.y+self.mainScroll.bounds.size.height);
    float val = (self.mainScroll.contentSize.height);
    if (offs==val)
    
        loading=YES;
        start_rec+=1;

        [self performSelectorInBackground:@selector(LoadData) withObject:nil];

    

并从服务器获取更多数据

-(void)LoadData

[self.actind startAnimating];
[self.actind setHidden:NO];
loading=YES;

NSString *serverURL =  [[[NSBundle mainBundle] infoDictionary] objectForKey:@"BaseURL"];
NSString *queryString=[NSString stringWithFormat:@"GetDisasterAlertsJson?authCode=%@&lastUpdated=%@&version=%@&langId=%@&pageNo=%@&noOfMessages=%@",dm.strAuthCode,lastUpdate,@"1.0",@"1",[NSString stringWithFormat:@"%i",start_rec],@"5"];
NSString *urlString=[NSString stringWithFormat:@"%@%@",serverURL,queryString];
// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
// Create url connection and fire request
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) 
    if (!data) 
        NSLog(@"%s: sendAynchronousRequest error: %@", __FUNCTION__, connectionError);
        return;
     else if ([response isKindOfClass:[NSHTTPURLResponse class]]) 
        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
        if (statusCode != 200) 
            NSLog(@"%s: sendAsynchronousRequest status code != 200: response = %@", __FUNCTION__, response);
            return;
        
    

    NSError *parseError = nil;
    NSData *dataXMLRemoved=[self ReplaceXMLData:data];
    NSLog(@"======= Data XML Removed ======== %@",dataXMLRemoved);
    dictionary = [NSJSONSerialization JSONObjectWithData:dataXMLRemoved options:NSJSONReadingAllowFragments error:&parseError];

    if (!dictionary) 
        NSLog(@"%s: JSONObjectWithData error: %@; data = %@", __FUNCTION__, parseError, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        resNull=NO;
        return;
    


    // now you can use your `dictionary` object

    else
    
        NSLog(@"JSON Dictionary================ %@",dictionary);
        array=[dictionary objectForKey:@"Cmessage"];
        NSLog(@"Array ####### %@",array);
        resNull=NO;
        loading=NO;
        [self.actind stopAnimating];
        [self.actind setHidden:YES];
        [self setUI];


    
];

【问题讨论】:

在我将更多视图加载到底部后似乎不起作用 【参考方案1】:

我不确定这是否是您的问题,但默认情况下 UIScrollViews 会延迟触摸从过滤到嵌入视图的滚动性能。这可能会使按钮看起来不是每次都被触发,而实际上在嵌入式视图上触发触摸事件只需要大约一秒钟。

尝试在您的滚动视图上关闭此设置。

self.mainScroll.delaysContentTouches = NO;

【讨论】:

但是它不能滚动。 并且在我将其设置为 NO 后,根本没有按钮不可点击。在我的情况下,我最多可以点击第 3 个 btn,其余的东西是不可点击的。位于屏幕长度下方的类似按钮不可点击。但是如果刷新发生了,这些按钮又可以点击了,但只有 3 或 4 个,其余按钮不起作用

以上是关于对于以编程方式创建的 UIButton,有时不会触发按钮单击事件的主要内容,如果未能解决你的问题,请参考以下文章

无法隐藏以编程方式创建的 UIButton

点击 UIButton 以编程方式创建另一个 UIButton

更改以编程方式创建的单击 UIButton 的背景图像

快速以编程方式创建后如何在情节提要中链接 UIButton

隐藏以编程方式为标签创建的 UIButton

以编程方式创建 UIButton 比使用情节提要模糊