2016-01-09 3 views
1

UPDATTE:UICollectionView Reload данных не работает обновление CollectionView

Я забыл упомянуть, что CollectionView находится в правой части в Split View Controller, и с левой стороны, у меня есть Tableview. Когда строка выбрана, я передаю новый АДРЕС FEED и запускаю метод refreshFeed с правой стороны.

У меня есть представление коллекции, которое анализирует данные из XML. Когда нажимается определенная кнопка, я хочу, чтобы она очистила CollectionView и загрузила данные из другого XML, оба из которых находятся в Интернете. Я использую классы ASIHTTPRequest и GDATAXML, чтобы помочь мне снять это. Вот мой код. Я могу проверить через журналы, что NSMutableArray очищен и успешно заполнен другим XML, но reloadData никогда не происходит, поскольку cellForItem не получает вызов во второй раз. Где я перепутался?

@interface RightViewController() 
@property (nonatomic, strong) IBOutlet UICollectionView *collectionView; 

@end 

@implementation RightViewController 

@synthesize allEntries = _allEntries; 
@synthesize feeds = _feeds; 
@synthesize queue = _queue; 
@synthesize webViewController = _webViewController; 
@synthesize activity; 
@synthesize webViewController2 = _webViewController2; 



@synthesize nameit2; 
@synthesize nowplaying; 
@synthesize entryofmp3 = _entryofmp3; 
@synthesize nameit; 
@synthesize progress; 
@synthesize lastSelection; 
@synthesize backgroundTaskIdentifier, theurl; 
@synthesize thetable, thepath, downloadlabel, receivedData, progressbutton; 


-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    return 1; 
} 
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
    return [_allEntries count]; 
} 
- (void)loadFirstTime { 
     self.allEntries = [NSMutableArray array]; 

     self.queue = [[NSOperationQueue alloc] init]; 


    if (_feedAddress == nil) { 
     _feedAddress = @"http://www.316apps.com/AIMAPPLETV/AIMSeries.xml"; 
    } 
    self.feeds = [NSArray arrayWithObjects:_feedAddress, 
        nil]; 
    for (NSString *feed in _feeds) { 
     NSLog(@"Running Fine"); 
     NSURL *url = [NSURL URLWithString:feed]; 
     ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
     [request setDelegate:self]; 
     [_queue addOperation:request]; 
    } 
    NSLog(@"Still Good"); 
    //[self.collectionView reloadData]; 


} 
-(void)changeFeed { 
    [_allEntries removeAllObjects]; 
    _feedAddress = @"http://www.316apps.com/AIMAPPLETV/AIMCON.xml"; 
    [self loadFirstTime]; 
    // self.queue = nil; 
    //_request.delegate = nil; 
// _request.delegate = nil; 

    // [_collectionView reloadData]; 
} 
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    // [self performSegueWithIdentifier:@"playMovies" sender:self]; 
    RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row]; 
    NSString *wifiStreamAddress = entry.articleUrl; 
    AVPlayer *player = [[AVPlayer alloc] initWithURL: [NSURL URLWithString: wifiStreamAddress] ]; 
    AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; 
    playerViewController.player = player; 

    // Keep pointers to player and controller 
    self.player = player; 
    self.playerViewController = playerViewController; 



    [self presentViewController: playerViewController animated: true completion: ^{ 
     [self.player play]; 
    }]; 


} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    // Make sure your segue name in storyboard is the same as this line 
    if ([[segue identifier] isEqualToString:@"playMovies"]) 
    { 
     PlayMovies *userViewController = [segue destinationViewController]; 

     //if you need to pass data to the next controller do it here 
    } 
} 
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 


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

    static NSString *cellIdentifier = @"cvCell"; 

    CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 

     [cell.theimage setImageWithURL:[NSURL URLWithString:entry.articleImage] placeholderImage:[UIImage imageNamed:@"[email protected]"]]; 

    cell.theimage.adjustsImageWhenAncestorFocused = YES; 
    cell.theimage.clipsToBounds = false; 




    return cell; 
} 

- (void)viewDidLoad { 
     [super viewDidLoad]; 

    self.allEntries = [NSMutableArray array]; 
    self.queue = [[NSOperationQueue alloc] init]; 
     [self loadFirstTime]; 

} 
-(void) viewWillAppear:(BOOL)animated { 

} 

- (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 *articleTitle = [item valueForChild:@"title"]; 
      NSString *articleUrl = [[[[item elementsForName: @"enclosure"] lastObject] attributeForName: @"url"] stringValue]; 
      NSString *articleDateString = [item valueForChild:@"pubDate"]; 
      NSString *picture = [[[[item elementsForName: @"itunes:image"] lastObject] attributeForName: @"href"] stringValue]; 
      NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822]; 
      RSSEntry *entry = [[RSSEntry alloc] initWithBlogTitle:blogTitle 
                 articleTitle:articleTitle 
                 articleUrl:articleUrl 
                 articleDate:articleDate 
                 articleImage:picture]; 


      [entries addObject:entry]; 
      NSLog(@"%@", entries); 
     } 
    } 
    [self.collectionView reloadData]; 
} 

- (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 { 
    NSLog(@"Request Finished"); 
    [_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]; 


       } 

      }]; 

     } 
    }]; 

} 

- (void)requestFailed:(ASIHTTPRequest *)request { 
    NSError *error = [request error]; 
    NSLog(@"Error: %@", error); 
    [self loadFirstTime]; 
} 


- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

ВТОРАЯ UPDATE:

я медленно получаю где-то. Думаю, это было из-за того, что у меня не было настройки Segue. Я выписываю Segue из Cell of the LeftView TableView в Control View View Controller и настраивается как ShowDetail и называет его. Тогда в LeftViewController:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (indexPath.row == 1) { 
     [self performSegueWithIdentifier:@"doingIt" sender:self]; 

    } 
} 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    // Make sure your segue name in storyboard is the same as this line 
    if ([[segue identifier] isEqualToString:@"doingIt"]) 
    { 

     self.rightViewController = [[RightViewController alloc] init]; 
       [self.rightViewController refresheyc]; 

     //if you need to pass data to the next controller do it here 
    } 
} 

В RightViewController у меня есть:

-(void)refresheyc { 
    NSLog(@"This Sucks"); 
    [self.allEntries removeAllObjects]; 
    [self.collectionView reloadData]; 
    self.allEntries = nil; 
    self.queue = nil; 
    self.allEntries = [NSMutableArray array]; 

    self.queue = [[NSOperationQueue alloc] init]; 




    self.feeds = [NSArray arrayWithObjects:@"http://www.316apps.com/AIMAPPLETV/AIMCON.xml", 
        nil]; 
    for (NSString *feed in _feeds) { 
     NSURL *url = [NSURL URLWithString:feed]; 
     NSLog(@"URL%@", url); 
     ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
     [request setDelegate:self]; 
     [_queue addOperation:request]; 
    } 

} 

клетки в CollectionView сразу исчезают, но через несколько секунд, все они возвращаются так же, не изменяя XML вообще , но я получаю это:

2016-01-09 14:37:31.542 AIM-TV[7965:522091] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release. 
Stack:(
    0 CoreFoundation      0x0000000109fa6ff5 __exceptionPreprocess + 165 
    1 libobjc.A.dylib      0x000000010d45cdeb objc_exception_throw + 48 
    2 CoreFoundation      0x0000000109fa6f2d +[NSException raise:format:] + 205 
    3 Foundation       0x000000010aa96341 _AssertAutolayoutOnMainThreadOnly + 79 
    4 Foundation       0x000000010a8f6d6e -[NSISEngine withBehaviors:performModifications:] + 31 
    5 UIKit        0x000000010c804eb8 -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 58 
    6 UIKit        0x000000010c804854 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 646 
    7 UIKit        0x000000010c804ec1 -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 67 
    8 UIKit        0x000000010c804589 -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 242 
    9 UIKit        0x000000010c80405d -[UIView(AdditionalLayoutSupport) _initializeHostedLayoutEngine] + 649 
    10 UIKit        0x000000010c7f652a -[UIView(UIConstraintBasedLayout) _initializeLayoutEngine] + 152 
    11 UIKit        0x000000010c7f652a -[UIView(UIConstraintBasedLayout) _initializeLayoutEngine] + 152 
    12 UIKit        0x000000010c804e24 -[UIView(AdditionalLayoutSupport) _layoutEngineCreateIfNecessary] + 62 
    13 UIKit        0x000000010c7f732b -[UIView(UIConstraintBasedLayout) _tryToAddConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 126 
    14 UIKit        0x000000010c7f75ef -[UIView(UIConstraintBasedLayout) _addConstraint:] + 274 
    15 UIKit        0x000000010c7fd247 -[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 779 
    16 UIKit        0x000000010c806270 -[UIView(AdditionalLayoutSupport) updateConstraints] + 224 
    17 UIKit        0x000000010c80559b -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 550 
    18 UIKit        0x000000010c805866 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 198 
    19 UIKit        0x000000010c8054aa -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 309 
    20 UIKit        0x000000010c805866 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 198 
    21 UIKit        0x000000010c8054aa -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 309 
    22 UIKit        0x000000010c804ec1 -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 67 
    23 UIKit        0x000000010c80583a -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:forSecondPass:] + 154 
    24 UIKit        0x000000010c805e9e __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 98 
    25 UIKit 
+0

Вы указали делегат 'collectionView'' RightViewController'? –

+0

Да, на моей раскадровке у меня есть коллекция collectionView, которую я объявил в верхней части, перетаскиваемой в CollectionView, а затем в ссылку Referouts Outlets для dataSource, а также делегата. Он загружает коллекциюView просто отлично в первый раз, но потом, пытаясь заставить его перезагрузить, ничего не происходит[email protected] – user717452

+0

@ user717452: Где ваш метод 'refreshfree'? –

ответ

1

Вы не можете обновлять элементы пользовательского интерфейса в фоновом потоке. [self.collectionView reloadData] вызывается из parseRss, который сам называется формой parseFeed, вызываемой операцией на _queue. если _queue не обрабатывается основным потоком, вы получите непредсказуемые результаты в коллекцииView и, скорее всего, сбой.

Вы должны отправить свой запрос на [self.collectionView reloadData] в основной поток.

dispatch_async(dispatch_get_main_queue(), { self.collectionView.reloadData() }) 

(это Swift синтаксис, я не знаком с Obj-C, извините)

+0

Я пробовал, но это не помогло мне. Я использую Swift 3. – nyxee

+0

В swift у меня такая же странная проблема, но ее некоторые как работают –

+0

Я разместил здесь свою проблему: [CollectionViewController.reloadData() с данными с сервера анализа) (https://stackoverflow.com/questions/45232915/collectionviewcontroller-reloaddata-с-данными из--а-синтаксического анализа-сервера) – nyxee

0

Проблема действительно странно, но это как-то работает для меня, как, я добавил код обновления ограничений в анимация блок,

UIView.animate(withDuration: 0.5, animations: {() -> Void in 

    //update constraints here 

    self.view.layoutIfNeeded() 
    self.collectionView.layoutIfNeeded() 

}) 

self.collectionView.reloadData() 
0

Как указано в ответе Алена, это происходит потому, что изменения пользовательского интерфейса должны быть обработаны основной поток. Я вижу, что вопрос был опубликован с использованием Objective C и ответил в Swift, поэтому я подумал, что опубликую версию Objective C, если кому-то это понадобится.

dispatch_async(dispatch_get_main_queue(),^{ 
    [self.collectionView reloadData]; 
}); 
Смежные вопросы