2014-04-01 1 views
0

인앱 설정 Table View Controller이 포함 된 간단한 애플리케이션이 있습니다. 사용자가 "App Themes"셀을 선택하면 에 삽입 된 UICollectionView으로 segues (푸시)합니다.UICollectionView가 처음으로 눈에 띄는 지연 시간을 가지고 있습니다.

이것은 각 셀에 이미지, 레이블 및 해당 테마가 선택되면 체크 표시 이미지가있는 3x4 형식의 12 셀입니다.

세포는 여기 클래스 내에서 동적으로로드되지만 처음에는 UICollectionView에 연결될 때 큰 지연이 있음을 눈치 챘을 것입니다. 계속되는 모든 시간 동안, 잘 작동하지만 아이폰 5에서는 몇 가지 극단적 인 눈에 띄는 지연이 있습니다. iOS 개발에 상당히 익숙합니다. 처음으로 뷰를 생성하는 방법과 관련이 있다는 느낌이 들지만, 확실하지 않아. 내 viewDidLoad에서

, 나는이 다음 changeAppThemes 방법은 본질적으로 NSUserDefaults와 보는을 통해 순환되는

- (void)viewDidLoad 
{ 
    self.title = @"Themes"; 
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; 
    [super viewDidLoad]; 
    self.cView.dataSource = self; 
    self.cView.delegate = self; 


    self.themeLabels = [[NSArray alloc] initWithObjects:@"Original", @"Peacock", @"Mystical", @"Zebra", @"Simplicity", @"Rainbow", @"Prosperity", @"Leopard", @"Hypnotic", @"Dunes", @"Twirl", @"Oceanic", nil]; 

    self.themeImages = @[[UIImage imageNamed:@"Newiphonebackground.png"], [UIImage imageNamed:@"peacock.png"], [UIImage imageNamed:@"Purplepink.png"], [UIImage imageNamed:@"PinkZebra.png"], [UIImage imageNamed:@"Greenish.png"], [UIImage imageNamed:@"MarblePrint.png"], [UIImage imageNamed:@"Prosperity.png"], [UIImage imageNamed:@"leopard.png"], [UIImage imageNamed:@"CircleEffect.png"], [UIImage imageNamed:@"Orange3.png"], [UIImage imageNamed:@"ReddishBlack.png"], [UIImage imageNamed:@"bluey.png"]]; 

    [self changeAppThemes]; 

} 

하는 테마를 적용 할 수 있습니다.

- (void)changeAppThemes 
{ 
    self.selectedTheme = [[NSUserDefaults standardUserDefaults] objectForKey:@"Theme"]; 

    if ([self.selectedTheme isEqualToString:@"Mystical"]) 
    { 
     self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Purplepink.png"]]; 
     UIImage *navBackgroundImage = [[UIImage imageNamed: @"Purplepinknav"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 
     [self.navigationController.navigationBar setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault]; 

     UIImage *tabBackground = [[UIImage imageNamed:@"SolidPurple.png"] 
            resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 
     [self.tabBarController.tabBar setBackgroundImage:tabBackground]; 
    } 

etc 

viewWillAppear은 다음과 같습니다

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self changeAppThemes]; 

    self.selectedThemeString = [[NSUserDefaults standardUserDefaults] objectForKey:@"Selection"]; 

    if ([self.selectedThemeString isEqualToString:@"Original"]) 
    { 
     self.checkedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 
    } 

    else if ([self.selectedThemeString isEqualToString:@"Oceanic"]) 
    { 
     self.checkedIndexPath = [NSIndexPath indexPathForRow:11 inSection:0]; 
    } 

    [self.cView reloadData]; 

} 

viewWillAppear 오늘은 다른 코드없이 changeAppThemes 메서드 호출을했지만, 처음 UICollectionView에 segueing 때 여전히 응답하지 전에.

cellForItemAtIndexPath이다 : 나는 changeAppThemes에 전화를 걸 경우

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

    ThemeCell *themeCell = (ThemeCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"Theme Cell" forIndexPath:indexPath]; 

    NSString *cellData = [self.themeLabels objectAtIndex:indexPath.row]; 

    themeCell.cellLabel.text = cellData; 
    themeCell.cellImages.image = self.themeImages[indexPath.row]; 
    UIImageView *dot = [[UIImageView alloc]initWithFrame:CGRectMake(5, 0, 1, 2)]; 
    dot.image=[UIImage imageNamed:@"check-white-hi.png"]; 

    if([self.checkedIndexPath isEqual:indexPath]) 
    { 
     NSLog(@"Loaded"); 
     themeCell.backgroundView = dot; 
     [themeCell addSubview:dot]; 

    } 
    else 
    { 
     NSLog(@"Not Loaded"); 

     themeCell.backgroundView = nil; 
    } 

내가 변화해야 하는가? viewWillAppear에서 전화를 제거한 후 viewDidLoad에 남겨 두었고 그 반대의 경우도 마찬가지입니다. 두 경우 모두 처음으로 UICollectionView을 열면 응답 성은 매우 나빴습니다.

모든 의견은 정말 감사하겠습니다.

+0

이미지 크기를 확인하십시오. – NeverBe

+0

사실 매우 흥미로운 점입니다. 실제로 앱의 배경에 동일한 이미지를 사용하고 있습니다. 따라서 iPhone 5는이 컬렉션 셀의 이미지를 640x1136 크기로 표시합니다. 이제는 이미지 크기에 대해 언급 했으므로 조금 과장된 것 같습니다. 이미지의 크기를 크게 줄이고 테스트해야합니까? – amitsbajaj

+0

디자인 한대로 이미지의 크기를 사용하십시오. 망막의 경우 2를 곱합니다. – NeverBe

답변

1

먼저 "themeCell"을 다시 사용하지 마십시오 (최소한 보이지는 않음). 한 번만 인스턴스화 한 다음 지금처럼 다시 사용하십시오. 또한 당신의 viewDidLoad에서 "self.themeImages는"약간의 오버 헤드를 추가 할 수 있습니다

if(themeCell == nil) { 
    // Do all initialization here. For example the "dot" ImageView... 
} else { 
    // Reuse the "themeCell" here 
} 

,하지만 극단적 인 안 : 그래서 당신이 좋아하는 if 문을 추가하는 것이 좋습니다. 우리는 시작시 눈에 띄지 않는 MAX에서 60-100ms 정도를 이야기하고 있습니다. 그리고 또 다른 큰하지만 : - 정말 귀하의 이미지의 크기에 따라 달라집니다! 크기가 2-5MB라고 할 때 오버 헤드가 많이 발생하고 "Lazy loading"을 통해 이루어져야합니다.

또한 [self changeAppThemes]는 viewDidLoad 메서드에서 중복됩니다. 제거하면 아무것도 망가 뜨리지 않아야합니다.

+0

많은 감사의 말 @Alexander W - 늦은 답장에 대해 사과드립니다. 귀하의 답변에 감사드립니다. 상당히 프로그래밍에 익숙하지 않기 때문에 테마 셀 == nil을 사용하여 셀 재사용을 사용하는 방법을 잘 모릅니다. 이미지 뷰 인스턴스화 코드를 넣을 때 메소드의 다른 곳에서는 인식하지 못했기 때문입니다 . 그러나 이미지의 크기를 줄이고 uiimageview에 대한 속성을 만들고 viewDidLoad에서 인스턴스를로드하고 인스턴스화했습니다. 그게 큰 차이를 만든 것 같습니다. 이 코드를 올바르게 재사용하면 어떻게 될까요? – amitsbajaj

+0

그리고 viewDidLoad에서 self changeAppThemes를 제거했습니다. 언급 한대로 코드 실행에 차이를 만들지는 않았지만 속도가 향상 될 수있었습니다. 나는 이것을 세포 재사용으로 가장 올바른 방법으로 찾고있다. – amitsbajaj

+0

다음과 같은 것들이 있습니까? [self.cView registerClass : [ThemeCell class] forCellWithReuseIdentifier : @ "Theme Cell"];'loadView 또는 viewDidLoad? ThemeCell 구현의'initWithFrame : (CGRect) aRect' 메소드에서 셀의 서브 뷰를 추가하고 예를 들어'UIImageView * dot'의 초기화를 수행합니다. 희망이 도움이! –

2

비동기 적으로 이미지를로드하십시오. 아래의 변형을 고려하십시오.먼저 재사용해야 들어

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

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

    dispatch_async(queue, ^{ 
     //Do THIS 
     UIImage *localImage [self createImageObjectsforIndex:indexPath.row]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      //Do this when done 
      cell.image = localImage; 
     }); 

    }); 
+0

답장을 보내 주신 에릭과 늦게 답변 해 주신 것에 사과드립니다. 내가 처음부터 이미지의 크기를 줄였습니다. 그리고 차이가 나기는했지만 아직 100 % 빠르지는 확실치 않습니다. 그래서 저는 여러분의 제안에 따라 비동기 적으로 이것을 조사 할 것입니다. 대답에 대해 많은 감사드립니다. – amitsbajaj

+0

우선 순위가 높은 이미지를로드하는 것이 실제로 fps에 영향을 미치기 때문에 여기에서 DISPATCH_QUEUE_PRIORITY_BACKGROUND을 (를) 선호합니다. – kelin

1

세포, 세포 propotype에 점을 추가하고 순위 :

대신이 코드의

if([self.checkedIndexPath isEqual:indexPath]) 
{ 
    NSLog(@"Loaded"); 
    themeCell.backgroundView = dot; 
    [themeCell addSubview:dot]; 

} 
else 
{ 
    NSLog(@"Not Loaded"); 

    themeCell.backgroundView = nil; 
} 

사용이 :

themeCell.dot.hidden = !([self.checkedIndexPath isEqual:indexPath]); 

둘째, imageView 크기 (망막의 경우 x2)로 이미지 파일의 크기를 조정하십시오.

+0

Thanks @ NeverBe - 나는 어떤 이유로이 일을 할 수 없었지만 알렉산더의 대답에는 많은 행운이있었습니다. 이 질문에 시간을 내 주셔서 감사 드리며 올바른 방향으로 나를 가리 키기 때문에 답을 뽑았습니다. 다시 한 번 감사드립니다. – amitsbajaj

관련 문제