Search code examples
objective-cxcodeuitableviewios6uialertview

a specific instance of insertsubview at index not working in ios 6.0


I'm testing my ios app that has a deployment target of 5.0 and a base SDK of 6.1.

Everything works fine in ios 5.0, and ios 5.1, but in ios 6.0 I'm having an issue with inserting a subview at index. The subview is a tableview and the parent view is an uialertview that was created as a special class "UIAlertTableView." The alertview appears, but there appears to be nothing inserted. Before this, I had fixed an autorotation issue of the superview (which is in landscape) because, as it is well known ios 6.0 handles rotation differently, so now my superview appears correctly, but as I said, this alertview pops up with no table now. Am I suppose to be fixing autorotation issues for the tableview as well as the superview? I didn't think this would be necessary since the tableview is not declared in the imported class, is is declared within the parent viewcontroller. Or could this be because of some method that was deprecated in ios 6.0?

     /*UIAlertTableView.m   (the imported object class)*/
    @interface UIAlertView (private)
    - (void)layoutAnimated:(BOOL)fp8;
    @end

    @implementation UIAlertTableView

    @synthesize tableWidth;
    @synthesize tableHeight;
    @synthesize lowestView;
    @synthesize kTablePadding;
    @synthesize alertDelegate;



    - (void)layoutAnimated:(BOOL)fp8 {
        [super layoutAnimated:fp8];
        [self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y - tableExtHeight/2, self.frame.size.width, self.frame.size.height + tableExtHeight)];

        // We get the lowest non-control view (i.e. Labels) so we can place the table view just below

        int i = 0;
        while (![[self.subviews objectAtIndex:i] isKindOfClass:[UIControl class]]) {
            lowestView = [self.subviews objectAtIndex:i];
            i++;
        }

        tableWidth = 262.0f;



        for (UIView *sv in self.subviews) {
            // Move all Controls down
            if ([sv isKindOfClass:[UIControl class]]) {
                sv.frame = CGRectMake(sv.frame.origin.x, sv.frame.origin.y + tableExtHeight, sv.frame.size.width, sv.frame.size.height);
            }
        }

    }

    - (void)show{
        [self prepare];
        [super show];
    }

    - (void)prepare {
        if (tableHeight == 0) {
            tableHeight = 150.0f;
        }
        kTablePadding = 8.0f;

        tableExtHeight = tableHeight + 2 * kTablePadding;

        [self setNeedsLayout];
    }


    @end

    /*the UIAlertTableView class is imported into the myViewController header file*/


   /*myViewController.m*/

    @implementation myViewController
    @synthesize myTableView;
    @synthesize alert;
    @synthesize imageView;
    @synthesize scrollView;
    @synthesize models;
    @synthesize picked;





    #pragma myTableView

    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


        return [models count];    

    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {

            cell = [[UITableViewCell alloc]
                    initWithStyle:UITableViewCellStyleDefault
                    reuseIdentifier:CellIdentifier];

        }




        // now configure the cell

        cell.textLabel.text = [models objectAtIndex:[indexPath row]];
        [cell setAccessibilityTraits: UIAccessibilityTraitButton];




        return cell;


    }
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {



        if (returnedSetting && (indexPath.row == prevSelectedIndex)){
            returnedSetting = FALSE;






        }
    }

    -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        //index path to row that's selected 

        NSIndexPath *myIndexPath = [myTableView indexPathForSelectedRow];
        UITableViewCell *cell = [myTableView cellForRowAtIndexPath:myIndexPath];
        labelText = cell.textLabel.text;
        selectedModel = cell.textLabel.text;


    }
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

        NSIndexPath *myIndexPath = [tableView indexPathForSelectedRow];
        prevSelectedIndex = myIndexPath.row;
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:myIndexPath];
        [alert dismissWithClickedButtonIndex:0 animated:YES];
        labelText = cell.textLabel.text;
        selectedModel = cell.textLabel.text;


        [self dismissModalViewControllerAnimated:YES];


    }



    -(void)removeButton{
        [UIView animateWithDuration:1.5
                              delay:1.5  
                            options:UIViewAnimationCurveEaseInOut 
                         animations:^ {
                             eButton.alpha = 0;

                         } 
                         completion:^(BOOL finished) {


                         }];
    }




    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }

    - (void)didReceiveMemoryWarning
    {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];

        // Release any cached data, images, etc that aren't in use.
    }
    -(void)showAlertFor:(NSTimer *)timer{



        [alert show];
        myTableView.frame = CGRectMake(11.0f, alert.lowestView.frame.origin.y + alert.lowestView.frame.size.height + 2 * alert.kTablePadding, alert.tableWidth, alert.tableHeight);
        [alert insertSubview:myTableView atIndex:1];
         [myTableView performSelector:@selector(flashScrollIndicators) withObject:nil afterDelay:.3];


    }
    -(void)bringupAlertTableViewFor:(NSString *)dName atLocationOnScreen:(CGPoint)newPoint{

        if (([dName isEqualToString:@"hello"]){

            picked =TRUE;



            myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f) style:UITableViewStylePlain];



            alert = [[UIAlertTableView alloc] initWithTitle:dName
                                                    message:@"Choose from the table below:"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:nil];
            [alert setDelegate: alert.alertDelegate];

            models = [[NSMutableArray alloc]init];
            myTableView.delegate = self;
            myTableView.dataSource = self;

            NSEntityDescription *entitydesc = [NSEntityDescription entityForName:@"Decisions" inManagedObjectContext:context];
            NSFetchRequest *request = [[NSFetchRequest alloc]init];
            [request setEntity:entitydesc];



            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dName == %@", dName];
            [request setPredicate: predicate];


            NSError *error;

            //matches found
            NSArray *matchingData = [context executeFetchRequest: request error: &error];



            for (NSManagedObject *obj in matchingData) {
                [models addObject:[NSString stringWithFormat:@"%@",[obj valueForKey: @"model"]]];


            }


            alert.tableHeight = 120;








            [alert show];


            myTableView.frame = CGRectMake(11.0f, alert.lowestView.frame.origin.y + alert.lowestView.frame.size.height + 2 * alert.kTablePadding, alert.tableWidth, alert.tableHeight);


            [alert insertSubview:myTableView atIndex:1];



            [myTableView performSelector:@selector(flashScrollIndicators) withObject:nil afterDelay:.3];




        }else{

            picked = TRUE;

            frame.origin.x = newPoint.x - 29; // new x coordinate
            frame.origin.y = 240; // new y coordinate

            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration: 1.5];

            [UIView commitAnimations];



            myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, 0.0f) style:UITableViewStylePlain];

            alert = [[UIAlertTableView alloc] initWithTitle:dName
                                                    message:@"Select a choice:"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:nil];
            [alert setDelegate: alert.alertDelegate];

            models = [[NSMutableArray alloc]init];
            myTableView.delegate = self;
            myTableView.dataSource = self;

            NSEntityDescription *entitydesc = [NSEntityDescription entityForName:@"Decisions" inManagedObjectContext:context];
            NSFetchRequest *request = [[NSFetchRequest alloc]init];
            [request setEntity:entitydesc];



            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deName == %@", dName];
            [request setPredicate: predicate];


            NSError *error;

            //matches found
            NSArray *matchingData = [context executeFetchRequest: request error: &error];



            for (NSManagedObject *obj in matchingData) {
                [models addObject:[NSString stringWithFormat:@"%@",[obj valueForKey: @"model"]]];


            }


            alert.tableHeight = 120;





                           [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(showAlertFor:) userInfo:nil repeats:NO];





            previousPoint = newPoint;




            } 







    }




    -(IBAction)singleTapImageView:(UITapGestureRecognizer *)sender {

        CGPoint pt = [sender locationInView: sender.view];




    //find out which was pressed




        if (  ((pt.x >= 52) && (pt.x <= 79)) && ((pt.y >= 269) && (pt.y <= 296))){
                   CGPoint newPoint = {45, (257 + 55)};

            [self bringupAlertTableViewFor:@"Choice1" atLocationOnScreen:newPoint];



        }


    }








    #pragma mark - View lifecycle




    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

    -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)sView{

     [self removeButton];
    }


    -(void)scrollViewDidScroll:(UIScrollView *)sView{

        eButton.alpha = .7;


    }

    -(void)scrollViewDidEndDecelerating:(UIScrollView *)sView
    {
        [self removeButton];



    }

    -(void)exitButtonPressed{
        [self dismissModalViewControllerAnimated:YES];
    }




    - (void)viewDidLoad
    {   


        UIImage *imageS = [UIImage imageNamed:@"ti.png"];

     imageView = [[TouchDetectingImageView alloc]initWithImage:imageS];
           [imageView setDelegate:self];

        imageView.frame = CGRectMake(20, 25, imageS.size.width,imageS.size.height);

        CGFloat newScrollWidth = imageView.image.size.width + 20;

        [scrollView setContentSize:(CGSizeMake(newScrollWidth, imageView.image.size.height))];


        [scrollView addSubview: imageView];


         imageView.contentMode = UIViewContentModeScaleToFill;
          UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapImageView:)];
        singleTap.numberOfTapsRequired = 1;
          [scrollView addGestureRecognizer:singleTap]; 




        UIImage *img = [UIImage imageNamed:@"backbutton.png"];
    CGRect frameForButton = CGRectMake(0, 3, img.size.width, img.size.height);
        eButton = [[exitButton alloc] initWithFrame:frameForButton];
        [eButton setDelegate:self];
        [eButton addTarget:self action:@selector(exitButtonPressed) forControlEvents:UIControlEventTouchUpInside];


        UITapGestureRecognizer *buttonTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(exitButtonPressed)];

        buttonTap.numberOfTapsRequired = 1;
        [eButton addGestureRecognizer:buttonTap];

        eButton.alpha = 0;


        [self.view addSubview:eButton];

            [super viewDidLoad];



       }

    - (void)viewDidAppear:(BOOL)animated
    {








        [super viewDidAppear:animated];



    }


    - (void)viewDidUnload
    {
        [self setScrollView:nil];

        [self setImageView:nil];



        [self setmyTableView:nil];
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        [scrollView flashScrollIndicators];
    }
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        // The menu is only going to support landscape orientations


        return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
    }
    - (NSInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
    }

    -(BOOL)shouldAutorotate{
        return YES;
    }

    @end

Solution

  • The reason(s) for this were:

    1) the call to layoutAnimated was being ignored

    2) it appears that ios 6 handles view hierarchy somewhat differently...

    3) ios 6.0 automatically scales to fit a 1136x640 display vs earlier version that scale to fit a 960x640 display.

    solutions were:

    • use a layoutsubviews call and layoutifneeded

    • also using conditional statements to find the ios version (e.g. greater_than_or_equal_to ios 6.0)