在调用[self.navigationController pushViewController:animated:]时花了很长时间将UIView推送到UINavigation控制器

时间:2013-01-18 12:29:23

标签: ios uinavigationcontroller

我正在尝试通过调用此UIView的方法将UIView推送到另一个UINavigationController

signupPageObj = [[SignupPage alloc]initWithNibName:@"SignupPage" bundle:nil];
[self.navigationController pushViewController:signupPageObj animated:YES]; 

但它已经卡住了一段时间来加载我的SignUpPage UIView。我不知道是什么原因,但因为viewDidLoad以及方法initWithNibName没有那么多自定义。

initWithNibName的整个代码如下:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) 
    {
        statusArray=[[NSMutableArray alloc] init];
        UILabel *labelforNavigationTitle = [[UILabel alloc] initWithFrame:CGRectZero];
        labelforNavigationTitle.backgroundColor = [UIColor clearColor];
        labelforNavigationTitle.font = [UIFont fontWithName:FONTSAVINGSBOND size:30.0];
        labelforNavigationTitle.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
        labelforNavigationTitle.textAlignment = UITextAlignmentCenter;
        labelforNavigationTitle.textColor = [UIColor whiteColor]; // change this color
        self.navigationItem.titleView = labelforNavigationTitle;
        labelforNavigationTitle.text = NSLocalizedString(@"Sign Up", @"");
        [labelforNavigationTitle sizeToFit];

    }
    return self;

}


-(void)viewDidLoad
{

    [super viewDidLoad];

    self.fullPathToFile=@"";
    self.gender=@"";
    strForGender=self.gender;
    labelInDatePicker.font=[UIFont fontWithName:FONTCENTURYGOTHICBOLD size:17.0];


    UIImage* imageCancel = [UIImage imageNamed:@"cancelbtn.png"];
    CGRect frameimg = CGRectMake(0, 0, (imageCancel.size.width)/2, (imageCancel.size.height)/2);


    UIButton *cancelButton = [[UIButton alloc] initWithFrame:frameimg];
    [cancelButton setBackgroundImage:imageCancel forState:UIControlStateNormal];
    [cancelButton addTarget:self action:@selector(cancelButtonclickedInAvtar)
         forControlEvents:UIControlEventTouchUpInside];
    [cancelButton setShowsTouchWhenHighlighted:YES];



    self.pickerBirthdayView.frame=CGRectMake(0,460,320,252);
    [self.view addSubview:self.pickerBirthdayView];

    self.avtarView.frame=CGRectMake(0,460,320,460);
    [self.view addSubview:self.avtarView];
    cancelButtonInAvtarView=[[UIBarButtonItem alloc]initWithCustomView:cancelButton];

    self.termsAndConditionPage.frame=CGRectMake(0,460,320,460);
    [self.view addSubview:self.termsAndConditionPage];


    if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)] ) 
    {
        UIImage *image = [UIImage imageNamed:@"titlebg.png"] ;
        [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
    }
    [self performSelector:@selector(settingScrollView) withObject:nil afterDelay:1.0];

    scrollPrevButton.hidden=YES;
    scrollNextButton.hidden=NO;

    isSectionExpanded=NO;
    checkForImage=2;
    termsAndConditionChecked=2;
    checkForBackgroundImage=10;
    start=10;


    UIImage* image1 = [UIImage imageNamed:@"backbtn.png"];
    CGRect frameimg1 = CGRectMake(0, 0, (image1.size.width)/2, (image1.size.height)/2);

    UIButton *backButton = [[UIButton alloc] initWithFrame:frameimg1];
    [backButton setBackgroundImage:image1 forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(popToRootViewController)
         forControlEvents:UIControlEventTouchUpInside];


    //    UIImage* image2 = [UIImage imageNamed:@"submitbtn.png"];
    //    CGRect frameimg2 = CGRectMake(0, 0, (image2.size.width)/2, (image2.size.height)/2);

    //    UIButton *submitButton = [[UIButton alloc] initWithFrame:frameimg2];
    //    [submitButton setBackgroundImage:image2 forState:UIControlStateNormal];
    //    [submitButton addTarget:self action:@selector(submitButtonPressed:)forControlEvents:UIControlEventTouchUpInside];


    UIImage* imageforTermsandConditionPage = [UIImage imageNamed:@"backbtn.png"];
    CGRect frameimgforTermsandConditionPage = CGRectMake(0, 0, (imageforTermsandConditionPage.size.width)/2, (imageforTermsandConditionPage.size.height)/2);

    UIButton *backButtonforTermsandConditionPage = [[UIButton alloc] initWithFrame:frameimgforTermsandConditionPage];
    [backButtonforTermsandConditionPage setBackgroundImage:imageforTermsandConditionPage forState:UIControlStateNormal];
    [backButtonforTermsandConditionPage addTarget:self action:@selector(backtoSignupPage) forControlEvents:UIControlEventTouchUpInside];



    UIImage* imageforChooseIconPage = [UIImage imageNamed:@"backbtn.png"];
    CGRect frameimgforChooseIconPage = CGRectMake(0, 0, (imageforChooseIconPage.size.width)/2, (imageforChooseIconPage.size.height)/2);

    UIButton *backButtonforChooseIconPage = [[UIButton alloc] initWithFrame:frameimgforChooseIconPage];
    [backButtonforChooseIconPage setBackgroundImage:imageforTermsandConditionPage forState:UIControlStateNormal];
    [backButtonforChooseIconPage addTarget:self action:@selector(backtoSignupPage) forControlEvents:UIControlEventTouchUpInside];



    backButton1 = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    self.navigationItem.leftBarButtonItem = backButton1;

    //    submitButton1=[[UIBarButtonItem alloc]initWithCustomView:submitButton];
    //    self.navigationItem.rightBarButtonItem=submitButton1;

    backButtonInTermsAndCondition=[[UIBarButtonItem alloc]initWithCustomView:backButtonforTermsandConditionPage];
    backButtonInChooseIcon=[[UIBarButtonItem alloc]initWithCustomView:backButtonforChooseIconPage];


    CALayer *layer = [self.objTextView layer];
    [layer setMasksToBounds:YES];
    [layer setCornerRadius:10.0];
    [layer setBorderWidth:0.0];
    [layer setBorderColor:[[UIColor lightGrayColor] CGColor]];
}


-(void)settingScrollView
{
    arrOfImages=[NSArray arrayWithObjects:@"Avtar0.png",@"Avtar1.png",@"Avtar2.png",@"Avtar3.png",@"Avtar4.png",@"Avtar5.png",@"Avtar6.png",@"Avtar7.png",@"Avtar8.png",@"Avtar9.png",nil];

    pageControl.numberOfPages = kNumberOfPages;
    pageControl.currentPage = 0;
    pageControl = [[PageControl alloc] initWithFrame:rect] ;
    pageControl.frame = rect;
    pageControl.delegate=self;
    pageControl.numberOfPages=[arrOfImages count];
    pageControl.currentPage = self.currentPage;
    [self.view addSubview:pageControl];

    scrollV = [[UIScrollView alloc]init];
    scrollV.frame=CGRectMake(35,55,250,246);
    scrollV.backgroundColor=[UIColor clearColor];
    scrollV.delegate=self;
    scrollV.pagingEnabled=YES;
    self.scrollV.contentSize = CGSizeMake(self.scrollV.frame.size.width *kNumberOfPages, 220);

    self.scrollV.showsHorizontalScrollIndicator = NO;
    self.scrollV.showsVerticalScrollIndicator = NO;
    self.scrollV.scrollsToTop = NO;
    self.scrollV.delegate = self;

    [self.avtarView addSubview:scrollV];


    for(int k =0;k<arrOfImages.count;k++)
    {

        UIButton *btn=[UIButton  buttonWithType:UIButtonTypeCustom];
        btn.tag=k;
        btn.imageView.contentMode= UIViewContentModeScaleAspectFit;
        [btn setImage:[UIImage imageNamed:[arrOfImages objectAtIndex:k]] forState:UIControlStateNormal];
        [btn setImage:[UIImage imageNamed:[arrOfImages objectAtIndex:k]] forState:UIControlStateHighlighted];
         btn.frame=CGRectMake((self.scrollV.frame.size.width * k),0, 250,241);
        [btn addTarget:self action:@selector(setImageInScrollView:) forControlEvents:UIControlEventTouchUpInside];
        [self.scrollV addSubview:btn];
    }

}

如果有人对此有任何建议或解决方案,我会很高兴。

1 个答案:

答案 0 :(得分:2)

我注意到你的settingScrollView正在加载一堆图像(特别是如果它们很大)可能很慢。这也是对内存的过度使用。这个问题有两种常见的解决方案:

  1. 您可以使用异步图像加载。而是将图像加载到主队列中,您可以使用GCD(或任何并发技术)在后台加载图像,然后将图像视图image属性的设置调度回主队列。这解决了性能问题,但不解决内存问题。

  2. 更好的是,您可以使用延迟加载,仅加载当前可见图像的图像。然后将视图控制器配置为UIScrollViewDelegate,当用户滚动到下一个图像时,然后加载它。你可以做一个加载当前图像和“下一个”图像的变体,当用户滚动到下一个图像时,你懒洋洋地加载新的“下一个”图像。我的第一个观察结果是,大多数延迟加载技术也采用异步图像加载。


  3. <强>更新

    显然,如果您更换了以下内容,那么您的屏幕演示会有所改善:

    [self performSelector:@selector(settingScrollView) withObject:nil afterDelay:1.0];
    

    只是:

    [self settingScrollView];
    

    但我认为你推迟了一秒钟是有原因的。也许你不喜欢加载十张图片所带来的延迟,因此你不想放慢整个用户界面的速度。因此,您可以使用我的第一种技术,即异步加载图像,以便在加载图像时不会阻止用户界面。如果您想这样做,可以使用以下内容替换for中的settingScrollView循环:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    for (int k = 0; k < arrOfImages.count; k++)
    {
        UIButton *btn = [UIButton  buttonWithType:UIButtonTypeCustom];
        btn.tag = k;
        btn.imageView.contentMode = UIViewContentModeScaleAspectFit;
        dispatch_async(queue, ^{
    
            // retrieve the image in a background queue
    
            UIImage *image = [UIImage imageNamed:[arrOfImages objectAtIndex:k]];
    
            // and now update the image property in your UI in the main queue
    
            dispatch_async(dispatch_get_main_queue(), ^{
                [btn setImage:image forState:UIControlStateNormal];
                [btn setImage:image forState:UIControlStateHighlighted];
    
                btn.frame=CGRectMake((self.scrollV.frame.size.width * k),0, 250, 241);
                [btn addTarget:self action:@selector(setImageInScrollView:) forControlEvents:UIControlEventTouchUpInside];
                [self.scrollV addSubview:btn];
            });
        });
        // btn.frame=CGRectMake((self.scrollV.frame.size.width * k),0, 250, 241);
        // [btn addTarget:self action:@selector(setImageInScrollView:) forControlEvents:UIControlEventTouchUpInside];
        // [self.scrollV addSubview:btn];
    }
    

    话虽如此,通过imageNamed加载图像通常不会那么慢(尽管如果图像真的很大,它可以引入一个可观察的,如果适度的延迟)。但是上面的代码将进一步最小化从持久存储加载图像所带来的用户界面延迟。假设你的图像大约是250x241,性能改善是适度的(当然,它返回到我的用户界面十倍之后,但是因为,但同步加载图像只需要0.05秒,而异步加载它们,我的UI返回0.005秒)。这种技术在拍摄非常流畅的桌面滚动或者从网上加载图像时非常有用,但是不清楚它在这里是否值得(除非你的图像很大)。

    我不会解决我的第二点,即图像的延迟加载,除非你告诉我们你有记忆问题。如果是这种情况,我们将imageNamed方法替换为imageWithContentsOfFile(因为imageNamed是一个非常粗略的缓存系统)并将其包装在适当的延迟加载方案中。但只有十张图片,你可能不需要去那里。所以我会推迟这个解决方案,除非你回来告诉我们你有严重的记忆问题。