2013-06-14 5 views
1

다음은 내 앱의 레이아웃입니다. Tab Bar Controller에 UICollectionView가 있습니다. 두 개의 서로 다른 XML 파일이 서버에 있습니다. 구독 구매에 따라 두 xml 중 하나가 구문 분석되고 각 항목이 UICollectionView에 표시되는 배열에 추가됩니다. MKiCloudSync를 사용하여 구독이 유효한지 여부를 결정하는 방법으로 iCloud에 NSUserDefault 값을 저장하여 사용자가 여러 장치에서 앱에 액세스 할 수 있도록합니다.UICollectionView 셀이 동일한 항목을 너무 많이로드하는 중

AppDelegate 구현 파일에서 didFinishLaunchingWithOptions에 대해 [MKiCloudSync start];을 호출합니다. UICollectionViewController 파일에서

는, 레이아웃은 기본적으로 이것이다 :

있는 viewDidLoad는 MKiCloudSync 변경에 대한 리스너를 추가합니다. 변경이 이루어지면 코드를 실행하여 UI를 업데이트합니다. viewWillAppear는 NSUserDefaults를 검사하여 유료 또는 무료 XML을로드해야하는지 여부를 확인하고이를 기반으로 구문 분석합니다. 사용자에게 가입이 없으면 오른쪽 막대 버튼 항목을 사용하여 코드를 구입할 수 있습니다. 코드가 성공하면 유료 XML을 파싱하는 refreshpaid 코드가 실행됩니다.

이것은 이론상의 설정입니다. Ad Hoc 빌드에서 내 장치에서 앱을 실행하고 샌드 박스 환경에서 구독을 구입했습니다. 유료 XML에서 사용할 수있는 추가 콘텐츠를 표시해야하므로 UI가 업데이트되었습니다.

그런 다음 앱을 삭제하고 기기를 다시 시작한 다음 Ad Hoc 빌드를 다시 설치하여 iCloud 동기화가 작동하는지 확인했습니다. 앱이 시작될 때마다 모든 항목에 대해 11 개의 셀이 표시되었습니다 (새로 고침하는 코드가 어떻게 든 11 번 호출 됨). 다른 탭으로 이동하여 다시 돌아 오거나 셀을 클릭하여 다시 팝업하면 XML 자체에서 항목 하나당 1 개의 셀만 표시됩니다.

- (void)viewDidLoad { 
     [super viewDidLoad]; 
      [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updatetheui) name: NSUserDefaultsDidChangeNotification object: nil]; 
      UINib *cellNib = [UINib nibWithNibName:@"NibCell" bundle:nil]; 
     [self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"]; 
     self.collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"shelves.png"]]; 


    } 
-(void)updatetheui { 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

    NSString *status = [defaults objectForKey:@"Pay?"]; 
    NSString *expirationdate = [defaults objectForKey:@"expiration"]; 
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
    [dateFormat setDateFormat:@"MM/dd/yyyy"]; 
    NSDate *date = [dateFormat dateFromString:expirationdate]; 
    NSLog(@"Date: %@", [dateFormat stringFromDate:date]); 

    if ([status isEqualToString:@"PaidUp"]|([date timeIntervalSinceNow] > 0.0)) { 
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Status" style:UIBarButtonItemStyleBordered target:self action:@selector(statusofsubscription)]; 
     self.navigationItem.leftBarButtonItem = nil; 
     NSLog(@"UPDATEUI PAY"); 
     [_allEntries removeAllObjects]; 
     [self.collectionView reloadData]; 
     [self refreshpaid]; 

    } else { 
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Subscribe" style:UIBarButtonItemStyleBordered target:self action:@selector(buyButtonTapped:)]; 
     self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Restore" style:UIBarButtonItemStyleBordered target:self action:@selector(timetorestore)]; 
     [_allEntries removeAllObjects]; 
     [self.collectionView reloadData]; 
     [self refreshfree]; 
     NSLog(@"UPDATEUI FREE"); 
    } 

} 
- (void)viewWillAppear:(BOOL)animated { 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

    NSString *status = [defaults objectForKey:@"Pay?"]; 
    NSString *expirationdate = [defaults objectForKey:@"expiration"]; 
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
    [dateFormat setDateFormat:@"MM/dd/yyyy"]; 
    NSDate *date = [dateFormat dateFromString:expirationdate]; 
    NSLog(@"Date: %@", [dateFormat stringFromDate:date]); 

    if ([status isEqualToString:@"PaidUp"]|([date timeIntervalSinceNow] > 0.0)) { 
       [self refreshpaid]; 
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Status" style:UIBarButtonItemStyleBordered target:self action:@selector(statusofsubscription)]; 
     self.navigationItem.leftBarButtonItem = nil; 
     NSLog(@"WILLAPPEARPAID"); 
    } 
    else { 
     [self refreshfree]; 
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Subscribe" style:UIBarButtonItemStyleBordered target:self action:@selector(buyButtonTapped:)]; 
     self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Restore" style:UIBarButtonItemStyleBordered target:self action:@selector(timetorestore)]; 

    } 
    //[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 
-(void)timetorestore { 
    [MKiCloudSync start]; 
    UIAlertView *syncing = [[UIAlertView alloc]initWithTitle:@"Syncing" message:@"Now attempting to restore your subscription from iCloud. If unsuccessful, your subscription may have expired, or you may need to try again in a stronger network." delegate:self cancelButtonTitle:@"Okay" otherButtonTitles: nil]; 
    [syncing show]; 
    [syncing release]; 
} 
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    return 1; 
    NSLog(@"1"); 
} 
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
     return [_allEntries count]; 
    NSLog(@"2"); 
} 
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; 
    [UIView animateWithDuration:5.0 
          delay:0 
         options:(UIViewAnimationOptionAllowUserInteraction) 
        animations:^{ 
         NSLog(@"animation start"); 
         [cell setBackgroundColor:[UIColor colorWithRed: 180.0/255.0 green: 238.0/255.0 blue:180.0/255.0 alpha: 1.0]]; 
        } 
        completion:^(BOOL finished){ 
         NSLog(@"animation end"); 
         [cell setBackgroundColor:[UIColor whiteColor]]; 
        } 
    ]; 
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200 

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    { 
     if (_webViewController2 == nil) { 
      self.webViewController2 = [[[WebViewController2 alloc] initWithNibName:@"WebViewController2" bundle:[NSBundle mainBundle]] autorelease]; 
     } 
     RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row]; 
     _webViewController2.entry = entry; 
     [self.navigationController pushViewController:_webViewController2 animated:YES]; 

    } 




    else { 
     if (_webViewController == nil) { 
      self.webViewController = [[[WebViewController alloc] initWithNibName:@"WebViewController" bundle:[NSBundle mainBundle]] autorelease]; 
     } 
     RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row]; 
     _webViewController.entry = entry; 
     [self.navigationController pushViewController:_webViewController animated:YES]; 
    } 
#endif 


} 
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 


    RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row]; 


    static NSString *cellIdentifier = @"cvCell"; 

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 

    UIImageView *titleLabel = (UIImageView *)[cell viewWithTag:100]; 
    UILabel *titleLabel2 = (UILabel *)[cell viewWithTag:200]; 

      NSString *thearticleImage = entry.articleImage; 
       [titleLabel setImageWithURL:[NSURL URLWithString:entry.articleImage] placeholderImage:[UIImage imageNamed:@"[email protected]"]]; 


    // [titleLabel2 setText:entry.articleTitle]; 






    return cell; 
} 
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries { 

    NSArray *channels = [rootElement elementsForName:@"channel"]; 
    for (GDataXMLElement *channel in channels) { 

     NSString *blogTitle = [channel valueForChild:@"title"]; 

     NSArray *items = [channel elementsForName:@"item"]; 
     for (GDataXMLElement *item in items) { 

      NSString *issueTitle = [item valueForChild:@"title"]; 
      NSString *issueURL = [item valueForChild:@"link"]; 
      NSString *articleDateString = [item valueForChild:@"pubDate"]; 
      NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822]; 
      NSString *issueCoverArt = [item valueForChild:@"guid"]; 
      NSLog(@"Title%@", issueTitle); 
      NSLog(@"Link%@", issueURL); 
      NSLog(@"Date%@", articleDateString); 
      NSLog(@"CoverArt%@", issueCoverArt); 
      RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle 
                 articleTitle:issueTitle 
                 articleUrl:issueURL 
                 articleDate:articleDate 
                 articleImage:issueCoverArt] autorelease]; 
      [entries addObject:entry]; 

     } 
    } 

} 

- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries { 

    if ([rootElement.name compare:@"rss"] == NSOrderedSame) { 
     [self parseRss:rootElement entries:entries]; 
    } else if ([rootElement.name compare:@"feed"] == NSOrderedSame) { 
     [self parseAtom:rootElement entries:entries]; 
    } else { 
     NSLog(@"Unsupported root element: %@", rootElement.name); 
    } 
} 

- (void)requestFinished:(ASIHTTPRequest *)request { 

    [_queue addOperationWithBlock:^{ 

     NSError *error; 
     GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData] 
                   options:0 error:&error]; 
     if (doc == nil) { 
      NSLog(@"Failed to parse %@", request.url); 
     } else { 

      NSMutableArray *entries = [NSMutableArray array]; 
      [self parseFeed:doc.rootElement entries:entries]; 

      [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

       for (RSSEntry *entry in entries) { 

        int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) { 
         RSSEntry *entry1 = (RSSEntry *) a; 
         RSSEntry *entry2 = (RSSEntry *) b; 
         return [entry1.articleDate compare:entry2.articleDate]; 
        }]; 

        [_allEntries insertObject:entry atIndex:insertIdx]; 

           [self.collectionView reloadData];  
       } 

      }]; 

     } 
    }]; 

} 
+1

(iOS 용 내 WFAsyncImageCell에서, 그것은 OS X의에서 동일한 원리는 대부분입니다) - 기회는 당신이 때문에'NSLog' 출력을 게시 할 수있는 우리가 할 수있는 더 쉽게 메서드를 호출? 또한 _allEntries가 추가되는 곳이 한 곳 밖에없는 것 같습니다. ('requestFinished :') 각 줄의 스택 추적/상태를 결정하기 위해 그 줄에 중단 점을 놓으려고 했습니까? –

+0

정확히 11 개의 셀을 항목별로 표시하는 것은 이상합니다. 이것은 거의 무작위 적이 지 않으므로 collectionView를 자극 할 수있는 것이 무엇인지 살펴 봐야만 "복제본"을 정확하게 표시 할 수 있습니다. XML에 11 개의 항목이 있습니까? – Kirualex

+0

'viewWillAppear :'와'updateTheUI :'메소드 모두에서'refreshFree :'또는'refreshPaid :'메소드를 호출 한 후에'collectionView'를 다시로드해야한다고 생각합니다. 그리고 또 하나,'viewDidLoad'에'userDefault' 옵저버를 만들고'viewWillDisappear :'에서 그것을 제거하고 있습니다. 따라서 탭을 변경하거나 셀을 선택하면 뷰는 관측자를 제거합니다. 그 후에는 사용자가 구매할 경우 알림을받지 못합니다. –

답변

0

하나의 가능성은 : 당신은 항상 무엇을 표시 얻을 것은 당신의 의도를 항상 있는지 확인해야

지금, 여기 내 UICollectionView.m 파일의 전체 코드입니다. 예를 들어이 걸릴 : 코드의 많은입니다

- (void)loadImage 
{ 
    if ([self.lastLoadedURL isEqual:self.imageURL]) 
    { 
     return; // The current image URL is being reloaded. Ignore. 
    } 

    self.imageView.image = nil; 
    NSURL *loadURL = self.imageURL; 
    dispatch_group_async(WFBackgroundTasks, 
         dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
                0), 
         ^
    { 
     // Get the image data. Possible check cached data 
     NSData *imageData = [NSData dataWithContentsOfURL:loadURL]; 
     UIImage *image = [[UIImage alloc] initWithData:imageData]; 
     if (!image) 
     { 
      // Oops, image file downloaded is bad. 
      image = [UIImage imageNamed:@"defaultFallback"]; 
     } 
     else 
     { 
      // Cache it. Not gonna implement here in the demo. 
     } 
     dispatch_async(dispatch_get_main_queue(), 
        ^
     { 
      if ([loadURL isEqual:self.imageURL]) 
      { 
       self.imageView.image = image; 
      } 
      else 
      { 
       // Oops, reload. 
       [self loadImage]; 
      } 
     }); 
    }); 
관련 문제