简体   繁体   English

从UIScrollview推送到另一个ViewController UIView SubView

[英]Pushing to another ViewController from UIScrollview UIView SubView

I've a scrollview that display information in a Carousel manner, what I want to do now is add click event on each and every View in the carousel, I was able to do that by adding UITapGestureRecongnizer* whenever it pushes, it Logs an error *nested push animation can result in corrupted navigation bar out and also it displays the wrong information Below is my code for loading the Carousel View and adding Click event, and also the data on the Carousel are gotten from a jSON and stored with NSObject in a **NSMutableArray*... 我有一个滚动视图,以轮播的方式显示信息,我现在要做的是在轮播中的每个View上添加click事件,我能够通过在每次按下时添加UITapGestureRecongnizer *来做到这一点,它会记录错误*嵌套的推送动画会导致导航栏损坏 ,并且显示错误的信息,以下是我的代码,用于加载Carousel View并添加Click事件,并且Carousel上的数据也是从jSON获取并与NSObject一起存储在** NSMutableArray * ...

 -(void)updateUI:(NSMutableArray *)array {

CGFloat contentOffset = 0.0f;

for (NSString *dis in carouselArray) {
    CGRect frame = CGRectMake(contentOffset, 0.0f, responseScroll.frame.size.width, responseScroll.frame.size.height);

    UIView *views = [[UIView alloc] initWithFrame:frame];
    views.backgroundColor = [UIColor clearColor];
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 130)];
    imageView.contentMode = UIViewContentModeScaleToFill;

    //imageView.image = [UIImage imageNamed:@"banner.png"];
    UITapGestureRecognizer *imageMove = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(moreViewMove)];
    imageMove.cancelsTouchesInView = NO;

    NSString *urls = [dis valueForKey:@"imageURL"];
    if ([urls  isEqual: @""]) {
        imageView.image = [UIImage imageNamed:@"banner.png"];
    } else {
        [imageView setImageWithURL:[NSURL URLWithString:urls]];
    }

    UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake(10, 132, 152, 21)];
    name.font = [UIFont fontWithName:@"Helvetica Bold" size:13];
    name.textColor = [UIColor blackColor];
    name.text = [dis valueForKey:@"name"];
    UILabel *address = [[UILabel alloc] initWithFrame:CGRectMake(10, 149, 194, 21)];
    address.font = [UIFont fontWithName:@"Helvetica Light" size:12];
    address.textColor = [UIColor blackColor];
    address.text = [dis valueForKey:@"address"];
    UILabel *km = [[UILabel alloc] initWithFrame:CGRectMake(278, 133, 42, 21)];
    km.font = [UIFont fontWithName:@"Helvetica" size:11];
    CLLocation *current = [[CLLocation alloc] initWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude];
    CLLocation *itemLoc = [[CLLocation alloc] initWithLatitude:[[dis valueForKey:@"lat"] doubleValue] longitude:[[dis valueForKey:@"lon"] doubleValue]];
    CLLocationDistance itemDist = [itemLoc distanceFromLocation:current]/1000;
    //NSLog(@"Distance: %f", itemDist);
    km.text = [[NSString alloc] initWithFormat:@"%.2fkm", itemDist];
    views.userInteractionEnabled = YES;
    [views addGestureRecognizer:imageMove];
    _starRating = [[EDStarRating alloc] initWithFrame:CGRectMake(234, 149, 78, 16)];
    _starRating.starImage = [UIImage imageNamed:@"star.png"] ;
    _starRating.starHighlightedImage = [UIImage imageNamed:@"starhighlighted.png"];
    _starRating.maxRating = 5.0;
    _starRating.delegate = self;
    _starRating.horizontalMargin = 0;
    _starRating.editable=NO;
    _starRating.rating= [[dis valueForKey:@"rating"] floatValue];
    _starRating.displayMode=EDStarRatingDisplayHalf;
    [views addSubview:imageView];
    [views addSubview:name];
    [views addSubview:address];
    [views addSubview:km];
    [views addSubview:_starRating];
    [responseScroll setUserInteractionEnabled:YES];
    [responseScroll addSubview:views];

    [responseScroll addGestureRecognizer:imageMove];

    contentOffset += views.frame.size.width;
    responseScroll.contentSize = CGSizeMake(contentOffset, views.frame.size.height);
}

}

And the code for handling View Click Events is below, I know I'm doing it wrong but I can't figure out what to do here. 下面是用于处理“查看点击事件”的代码,我知道我做错了,但是我不知道该怎么做。

-(void)moreViewMove {


for (NSString *dat in carouselArray) {
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    path = [path stringByAppendingPathComponent:@"u_id.plist"];
    NSMutableDictionary *dico = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

    NSString *place_id = [dat valueForKey:@"place_id"];
    NSString *place_reference = [dat valueForKey:@"place_reference"];

    CLLocation *current = [[CLLocation alloc] initWithLatitude:startLocation.coordinate.latitude longitude:startLocation.coordinate.longitude];
    CLLocation *itemLoc = [[CLLocation alloc] initWithLatitude:[[dat valueForKey:@"lat"] floatValue] longitude:[[dat valueForKey:@"lon"] floatValue]];
    CLLocationDistance itemDist = [itemLoc distanceFromLocation:current]/1000;

    UIDevice *device = [UIDevice currentDevice];
    NSString *u_id = [[device identifierForVendor] UUIDString];
    if ([dico objectForKey:@"u_id"]) {
        moreView *more = [self.storyboard instantiateViewControllerWithIdentifier:@"MoreView"];
        more.names = [dat valueForKey:@"name"];
        more.currentLat = [[NSString alloc] initWithFormat:@"%f", locationManager.location.coordinate.latitude];
        more.currentLon = [[NSString alloc] initWithFormat:@"%f", locationManager.location.coordinate.longitude];
        more.destinationLon = [dat valueForKey:@"lon"];
        more.destinationLat = [dat valueForKey:@"lat"];
        more.addressL = [dat valueForKey:@"address"];
        more.kilo = [[NSString alloc] initWithFormat:@"%.2fkm", itemDist];
        more.dataURL = @{@"type": @"details",@"u_id":[dico objectForKey:@"u_id"], @"place_id": place_id, @"place_reference": place_reference, @"device":@"server"};
        [self.navigationController pushViewController:more animated:YES];
    } 
}

}

Please, any help would be Appreciated... Thanks 请任何帮助将不胜感激...谢谢

The most unusual part of the code is the loop in moreViewMove . 代码中最不寻常的部分是moreViewMove的循环。 It looks like it will allocate and push up to N view controllers, where N is the number of elements in carouselArray . 看起来它将分配并推送到N个视图控制器,其中N是carouselArray的元素数。

The general pattern for this sort of thing is to have a loop that creates the views based on the model, a gesture recognizer to get the taps, and means to map the tap back to the model. 这种事情的一般模式是具有一个基于模型创建视图的循环,一个用于获取轻击的手势识别器以及将轻击映射回模型的手段。 Then the tap handler just looks up a single model item and performs navigation. 然后,点击处理程序仅查找单个模型项并执行导航。

The loop in updateUI: creates the subviews and gesture recognizers. updateUI:的循环updateUI:创建子视图和手势识别器。 A common means of mapping the views back to the model is with the view's tag property. 将视图映射回模型的一种常见方法是使用视图的tag属性。 In your updateUI, you would do something like this: 在updateUI中,您将执行以下操作:

UIView *views = [[UIView alloc] initWithFrame:frame];
views.tag = [carouselArray indexOfObject:dis];

// ...
// change the gesture recognizer selector to take a parameter
// notice the colon on the selector moreViewMove:
UITapGestureRecognizer *imageMove = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(moreViewMove:)];

Now in moreViewMove:, you can find out which index was tapped because the gesture recognizer will be sent as a param... 现在在moreViewMove:中,您可以找出被点击的索引,因为手势识别器将作为参数发送...

- (void)moreViewMove:(UITapGestureRecognizer *)gr {

    // don't put a loop in here.
    // probably don't build a dictionary in here that doesn't depend on which item was tapped

    UIView *theViewThatWasTapped = gr.view;
    NSInteger tag = theViewThatWasTapped.tag;

    // now, we can know what part of our model was tapped
    NSString *dis = carouselArray[tag];

    // check how you're doing with an NSLog
    NSLog(@"user tapped view with tag %ld model is %@", tag, dis);

    // your job now is to allocate a single view controller,
    // configure it with your model (dis) and push it

Do as little work as you can to configure the new vc. 尽可能少地配置新的vc。 Any init stuff that's invariant with respect to what part of the model was selected should be moved elsewhere, hopefully into that new view controller's initialization. 关于选择模型的哪个部分不变的任何初始化内容都应移至其他地方,希望移至该新视图控制器的初始化中。

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

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