1

최종 솔루션은 질문 아래에 주어진UIScrollView setNeedsDisplay가 작동하지 않습니까? 이 문제에

내 목표는 처음에 스크롤 뷰 내부에 각각의 이미지 뷰를 생성하는 이미지 선택기를 만드는 것입니다, 다음에 그 이미지 뷰에 대한 참조를 전달 메서드를 호출하여 비동기 적으로 imageview.image를 적절한 이미지로 업데이트합니다.

위대한 작품입니다.

내가으로 실행하는 문제는 그들이 만들어으로 그들을 하나 하나를 인쇄 할 수 내가 원하는 반면, 스크롤 뷰는, 방법의 끝에 배치에서 이미지보기 을 보여주고 있다는 점이다 (이미지 사용 가능 여부).

스크롤보기를 눌러을 스크롤하면 원하는대로 작동하지만 전혀 터치하지 않으면 이미지보기가 아닌 모든 이미지가 완료 될 때까지 화면이 흰색으로 유지됩니다. 로드.

self.view, scrollview 및 각 개별 이미지보기를 포함하여 모든보기에 대해 모든 곳에서 setNeedsDisplay를 배치 해 보았습니다. 무슨 일이야? 2월 7일에

- (void)viewDidLoad { 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
      [self setGridView]; 
    }); 
} 

- (void)setGridView { 
    // begin loading images 
    NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? @"2" : @""; 

    CGRect scrollframe = CGRectMake(0, 0, 300, 275); 
    UIScrollView * newscrollview; 
    newscrollview = [[UIScrollView alloc] initWithFrame:scrollframe]; 
    newscrollview.scrollEnabled = YES; 
    newscrollview.delegate = self; 
    [newscrollview setContentSize:CGSizeMake(300, (((ceilf([[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"Flickr_Dictionary"]] count]/4)) * (58+15)) + 15 + 58 + 15))]; 
    [picsMVContentCell.contentView addSubview:newscrollview]; 

    float currentx = 11; 
    float currenty = 17; 
    NSInteger index = 0; 

    for (NSDictionary * d in [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"Flickr_Dictionary"]]) { 

     // create button 
     UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; 
     button.frame = CGRectMake(currentx, currenty, 58, 58); 
     button.imageView.backgroundColor = [UIColor colorWithRed:(241/255.0) green:(241/255.0) blue:(241/255.0) alpha:1]; 
     button.imageView.contentMode = UIViewContentModeScaleAspectFit; 
     button.imageView.layer.cornerRadius = 6; 
     button.imageView.layer.masksToBounds = YES; 
     button.imageView.accessibilityLabel = [d objectForKey:@"id"]; 
     button.imageView.accessibilityValue = [d objectForKey:@"full"]; 
     button.imageView.tag = index++; 
     [button addTarget:self action:@selector(imageClick:) forControlEvents:UIControlEventTouchUpInside]; 

     UIImage * image = [MVImage imageWithImage:[UIImage imageNamed:@""] covertToWidth:58.0f covertToHeight:58.0f]; 
     [button setImage:image forState:UIControlStateNormal]; 

     [newscrollview addSubview:button]; 
     [newscrollview bringSubviewToFront:button]; 
     [newscrollview setNeedsDisplay]; 

     // calculate next image view position 
     currentx += (button.imageView.frame.size.width+15); 
     if (currentx >= 289) { 
      currentx = 11; 
      currenty += (button.imageView.frame.size.height+15); 
     } 

     // set image 
     NSString * nsuserdefault = [NSString stringWithFormat:@"Settings_SFThumbs%@_%@", retina, [d objectForKey:@"id"]]; 
     if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) { 
      MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]; 
      [button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal]; 
     } else { 
      [MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:@"thumb"] nsuserdefaultpath:nsuserdefault]; 
     } 
    } 
} 

편집, 2012 오후 3시 26분

이러한 변화는 바로 나를 가리키는에 대한 질문에 주어진 코드에 @Eugene에

감사와 관련된 모든 문제를 해결 방향

/* ---------- ---------- ---------- ---------- ---------- */ 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [[MVProject sharedInstance] syncLoadSF:0]; 

    self.newscrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 300, 275)]; 
    self.newscrollview.scrollEnabled = YES; 
    self.newscrollview.delegate = self; 
    [self.newscrollview setContentSize:CGSizeMake(300, (((ceilf(([[NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"Flickr_Dictionary"]] count]-1)/4)) * (58+15)) + 15 + 58 + 15))]; 
    [picsMVContentCell.contentView addSubview:self.newscrollview]; 

    [self setGridView]; 
} 

/* ---------- ---------- ---------- ---------- ---------- */ 

- (void)setGridView { 
    NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? @"2" : @""; 
    [self.newscrollview setNeedsDisplay]; 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSInteger index = 0; 
     for (NSDictionary * d in [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"Flickr_Dictionary"]]) { 
      // create button 
      UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];    
      button.frame = CGRectMake((11 + ((index%4)*(58+15))), (17 + ((floorf(index/4))*(58+15))), 58, 58); 
      button.imageView.backgroundColor = [UIColor colorWithRed:(241/255.0) green:(241/255.0) blue:(241/255.0) alpha:1]; 
      button.imageView.contentMode = UIViewContentModeScaleAspectFit; 
      button.imageView.layer.cornerRadius = 3; 
      button.imageView.layer.masksToBounds = YES; 
      button.imageView.accessibilityLabel = [d objectForKey:@"id"]; 
      button.imageView.accessibilityValue = [d objectForKey:@"full"]; 
      button.imageView.tag = index++; 
      [button addTarget:self action:@selector(imageClick:) forControlEvents:UIControlEventTouchUpInside]; 

      dispatch_sync(dispatch_get_main_queue(),^{ 
       [button setImage:[MVImage imageWithImage:[UIImage imageNamed:@""] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal]; 
       [self.newscrollview addSubview:button]; 
       [self.newscrollview bringSubviewToFront:button]; 
       [self.newscrollview setNeedsDisplay]; 

       // set image 
       NSString * nsuserdefault = [NSString stringWithFormat:@"Settings_SFThumbs%@_%@", retina, [d objectForKey:@"id"]]; 
       if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) { 
        MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]; 
        [button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal]; 
       } else { 
        [MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:@"thumb"] nsuserdefaultpath:nsuserdefault]; 
       } 
      }); 
     } 
    }); 
    [self.newscrollview setNeedsDisplay]; 
} 

답변

2

배경 스레드에서 작업 할 수 없습니다. 하위 뷰를 추가 할 때마다 주 스레드에서이 작업을 수행해야합니다. 그래서 당신은 동기화 블록에 드로잉 코드를 사용하는 것에 대한 구원, 즉 메인 큐

dispatch_sync(dispatch_get_main_queue(),^{ 
    [newscrollview addSubview:button]; 
    [newscrollview bringSubviewToFront:button]; 
    [newscrollview setNeedsDisplay]; 

    // calculate next image view position 
    currentx += (button.imageView.frame.size.width+15); 
    if (currentx >= 289) { 
     currentx = 11; 
     currenty += (button.imageView.frame.size.height+15); 
    } 

    // set image 
    NSString * nsuserdefault = [NSString stringWithFormat:@"Settings_SFThumbs%@_%@", retina, [d objectForKey:@"id"]]; 
    if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]) { 
     MVImage * thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:nsuserdefault]]; 
     [button setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f] forState:UIControlStateNormal]; 
    } else { 
     [MVProject asynchronousImageLoad:button.imageView urlpath:[d objectForKey:@"thumb"] nsuserdefaultpath:nsuserdefault]; 
    } 
    }); 
0

당신의 이미지를 설정 함께 갖는 문제에서 실행합니다. 당신의 노력은 모든 이미지 컨테이너를 scrollview에 추가하는 것입니다. 그런 다음 이미지가 준비되면 컨테이너에로드합니다. 이 작업을 수행하는 방법에는 두 가지가 있습니다.

먼저 모든 컨테이너를 스크롤보기에 추가하십시오. (로딩 인디케이터 또는 기본 이미지에 로딩 표시가 필요할 수 있습니다.)

1) 이미지 준비를위한 백그라운드 스레드를 만듭니다. 이미지가 준비되면 컨테이너에 추가합니다. (나는이 방법으로 더 많은 일을하고 고통을 느낀다.)

2) 커스텀 컨테이너를 생성하고 이미지 준비가되면 커스텀 컨테이너가 자신의 이미지를 추가하게한다.

예를 들어, 서버에서 이미지를로드하고 있습니다. 그래서 UIImageView의 커스텀 클래스 인 AsyncImage 클래스를 만들었습니다. 그리고 이미지 URL을 보내고 나머지는 처리하는 함수를 만들었습니다. 그것은 NSURLConnection을 생성하고 데이터가로드 될 때 self.image = [UIImage imageWithData:data];

+0

을 호출합니다. 감사합니다. 그러나 설명하는 내용은 이미 다음 줄을 통해 수행되고 있습니다.'[MVProject asynchronousImageLoad : button.imageView urlpath : [d objectForKey : @ "thumb" ] nsuserdefaultpath : nsuserdefault];'현재 작업하고있는 컨테이너를 만드는 것입니다.나는 button.imageViews가 일괄 적으로 (activityindicator와 함께)로드되기를 원하지 않는다. 나는 그들이 생성 될 때 하나씩 화면에 그려야한다. 위의 대답을 참조하십시오 ^^ –

관련 문제