简体   繁体   English

有时无法以编程方式创建的UIButton触发按钮单击事件

[英]Button click event not firing sometimes for programmatically created UIButton

I have added UIScrollView from the storyboard and inside that scroll view I have another UIView as a container view. 我已经从情节UIScrollView添加了UIScrollView ,并且在该滚动视图中有另一个UIView作为容器视图。 Behind the UIScrollView I have a UIImageView too as a sibling. UIScrollView后面,我也有一个UIImageView作为同级。 This is my View hierarchy. 这是我的View层次结构。

在此处输入图片说明

Now I am adding Views into this container view programmatically. 现在,我以编程方式将视图添加到此容器视图中。

-(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;


}

This is how I generate views. 这就是我生成视图的方式。

-(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;

//--------- VERTICLE LINE-------------- // ---------垂直线--------------

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;

} }

But my problem is this btnEvac is not clickable. 但是我的问题是btnEvac不可点击。 But sometimes I can click it only one time. 但是有时我只能单击一次。 This is my button click event. 这是我的按钮单击事件。

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

Sometimes this is firing in the very first time. 有时这是第一次出现。 After that nothing happens. 在那之后什么都没有发生。 I dont know whats the reason.I have set the User interaction enabled=YES to my scroll view and container view too. 我不知道是什么原因。我也将滚动和容器视图的用户交互设置为“启用”。 but not to the splash image view. 但不是初始图像视图。 I hope I dont wanna set that too. 我希望我也不想这样做。 Please help me. 请帮我。

Thanks 谢谢

This is how I load more view to the bottom 这就是我将更多视图加载到底部的方式

- (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];

    }
}

} }

And get more data from the server 并从服务器获取更多数据

-(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];


    }
}];

} }

I'm not sure if this is your problem but by default UIScrollViews delay touches from filtering through to embedded views for scrolling performance. 我不确定这是否是您的问题,但是默认情况下,UIScrollViews会延迟从筛选到嵌入视图的接触,以提高滚动性能。 This can make it seem like buttons aren't being triggered every time when really it just takes about a second for the touch event to fire on the embedded view. 这可能看起来好像并不是每次都触发按钮,而实际上仅需要一秒钟的时间,触摸事件就会在嵌入式视图上触发。

Try turning this setting off on your scrollview. 尝试在滚动视图上关闭此设置。

self.mainScroll.delaysContentTouches = NO;

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

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