对于以编程方式创建的 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,有时不会触发按钮单击事件的主要内容,如果未能解决你的问题,请参考以下文章