balabhv
balabhv

Reputation: 7

UITableViewCells don't resize for device or orientation change

I am trying to create an application that uses a UITableView with four custom UITableViewCells (It is a multiple selection table). The UITableViewCells only work on iPhone while in Portrait. In every other configuration, they appear for a split second before disappearing. Note: The custom cell I am using does not using a xib, everything is drawn programmatically.

My code for the UITableView:

#import "VariablesViewController.h"

@interface VariablesViewController ()

@end

@implementation VariablesViewController

@synthesize dataSource, selectedMarks;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

// displays the correct xib based on orientation and device type - called automatically upon view controller entry
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad) {
        if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
            [[NSBundle mainBundle] loadNibNamed:@"VariablesViewController~landscape_iPad"
                                          owner:self
                                        options:nil];
            [self viewDidLoad];
        } else {
            [[NSBundle mainBundle] loadNibNamed:@"VariablesViewController_iPad"
                                          owner:self
                                        options:nil];
            [self viewDidLoad];
        }
    } else {
        if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
            [[NSBundle mainBundle] loadNibNamed:@"VariablesViewController~landscape_iPhone"
                                          owner:self
                                        options:nil];
            [self viewDidLoad];
        } else {
            [[NSBundle mainBundle] loadNibNamed:@"VariablesViewController_iPhone"
                                          owner:self
                                        options:nil];
            [self viewDidLoad];
        }
    }

    [self.tableView reloadData];

}

// pre-iOS6 rotating options
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    self.view.autoresizesSubviews = YES;
    [self.tableView reloadData];
    return YES;
}

// iOS6 rotating options
- (BOOL)shouldAutorotate {
    self.view.autoresizesSubviews = YES;
    return YES;
}

// iOS6 interface orientations
- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];

    dataSource = [[NSMutableArray alloc] init];
    selectedMarks = [[NSMutableArray alloc] init];

    [dataSource addObject:@"X"];
    [dataSource addObject:@"Y"];
    [dataSource addObject:@"Z"];
    [dataSource addObject:@"Magnitude"];

    [self loadPrefs];

    self.navigationItem.rightBarButtonItem = doneButton;

    self.navigationItem.title = @"Record Settings";


}

- (void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
}

- (void) loadPrefs {

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

    BOOL x = [prefs boolForKey:@"X"];
    BOOL y = [prefs boolForKey:@"Y"];
    BOOL z = [prefs boolForKey:@"Z"];
    BOOL mag = [prefs boolForKey:@"Magnitude"];

    if (x)
        [selectedMarks addObject:@"X"];
    if (y)
        [selectedMarks addObject:@"Y"];
    if (z)
        [selectedMarks addObject:@"Z"];
    if (mag)
        [selectedMarks addObject:@"Magnitude"];


}

- (void) done {

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    [prefs setBool:[selectedMarks containsObject:@"X"] forKey:@"X"];
    [prefs setBool:[selectedMarks containsObject:@"Y"] forKey:@"Y"];
    [prefs setBool:[selectedMarks containsObject:@"Z"] forKey:@"Z"];
    [prefs setBool:[selectedMarks containsObject:@"Magnitude"] forKey:@"Magnitude"];

    [self.navigationController popViewControllerAnimated:YES];



}

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return 4;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIdent = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdent];

    if(cell == nil)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdent];

    cell.textLabel.text = [dataSource objectAtIndex:indexPath.row];
    if([selectedMarks containsObject:indexPath]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; }

    return cell;
}

#pragma mark - Table view delegate

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [selectedMarks addObject:indexPath];
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [selectedMarks removeObject:indexPath];
    }

    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

@end

I am using the CRTableViewCell class that I found on Github:

//
//  CRTableViewCell.m
//  CRMultiRowSelector
//
//  Created by Christian Roman on 6/17/12.
//  Copyright (c) 2012 chroman. All rights reserved.
//

#import "CRTableViewCell.h"

/* Macro for background colors */
#define colorWithRGBHex(hex)[UIColor colorWithRed:((float)((hex&0xFF0000)>>16))/255.0 green:((float)((hex&0xFF00)>>8))/255.0 blue:((float)(hex&0xFF))/255.0 alpha:1.0]
#define clearColorWithRGBHex(hex)[UIColor colorWithRed:MIN((((int)(hex>>16)&0xFF)/255.0)+.1,1.0)green:MIN((((int)(hex>>8)&0xFF)/255.0)+.1,1.0)blue:MIN((((int)(hex)&0xFF)/255.0)+.1,1.0)alpha:1.0]

/* Unselected mark constants */
#define kCircleRadioUnselected      23.0
#define kCircleLeftMargin           13.0
#define kCircleRect                 CGRectMake(3.5, 2.5, 22.0, 22.0)
#define kCircleOverlayRect          CGRectMake(1.5, 12.5, 26.0, 23.0)

/* Mark constants */
#define kStrokeWidth                2.0
#define kShadowRadius               4.0
#define kMarkDegrees                70.0
#define kMarkWidth                  3.0
#define kMarkHeight                 6.0
#define kShadowOffset               CGSizeMake(.0, 2.0)
#define kMarkShadowOffset           CGSizeMake(.0, -1.0)
#define kMarkImageSize              CGSizeMake(30.0, 30.0)
#define kMarkBase                   CGPointMake(9.0, 13.5)
#define kMarkDrawPoint              CGPointMake(20.0, 9.5)
#define kShadowColor                [UIColor colorWithWhite:.0 alpha:0.7]
#define kMarkShadowColor            [UIColor colorWithWhite:.0 alpha:0.3]
#define kBlueColor                  0x236ed8
#define kGreenColor                 0x179714
#define kRedColor                   0xa4091c
#define kMarkColor                  kGreenColor

/* Colums and cell constants */
#define kColumnPosition             50.0
#define kMarkCell                   60.0
#define kImageRect                  CGRectMake(10.0, 8.0, 30.0, 30.0)

@implementation CRTableViewCell

@synthesize isSelected = _isSelected;
@synthesize textLabel = label;
@synthesize imageView = imageView;
@synthesize renderedMark = _renderedMark;

- (void)drawRect:(CGRect)rect
{    
    _isSelected = NO;

    CGFloat posY = (rect.size.height/2) - kCircleRadioUnselected/2;

    CGRect unselectedCircleRect = CGRectMake(kCircleLeftMargin, posY, kCircleRadioUnselected, kCircleRadioUnselected);
    CGRect imageViewRect = CGRectMake(10, rect.size.height/2 - kCircleLeftMargin - 1, kMarkCell/2, kMarkCell/2);

    imageView.frame = imageViewRect; // Center the imageView

    UIBezierPath *unselectedCircle = [UIBezierPath bezierPathWithOvalInRect:unselectedCircleRect]; // Unselected circle centered
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    /* Unselected circle */
    CGContextSaveGState(ctx);
    {
        CGContextAddPath(ctx, unselectedCircle.CGPath);
        CGContextSetLineWidth(ctx, kStrokeWidth);
        CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
        CGContextSetRGBStrokeColor(ctx, 229/255.0, 229/255.0, 229/255.0, 1.0);
        CGContextDrawPath(ctx, kCGPathFillStroke);
    }
    CGContextRestoreGState(ctx);

    /* Column separator */
    CGContextSetRGBStrokeColor(ctx, 224/255.0, 224/255.0, 224/255.0, 1.0);
    CGContextSetLineWidth(ctx, 1.0);
    CGContextMoveToPoint(ctx, kColumnPosition, .0);
    CGContextAddLineToPoint(ctx, kColumnPosition, self.bounds.size.height);
    CGContextSetShouldAntialias(ctx, NO);
    CGContextStrokePath(ctx);

    [super drawRect:rect];
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        label = [[MarqueeLabel alloc] initWithFrame:CGRectMake(kMarkCell, .0, self.frame.size.width - kMarkCell, self.frame.size.height)];
        label.textColor = [UIColor blackColor];
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
        label.textAlignment = UITextAlignmentLeft;
        label.backgroundColor = [UIColor clearColor];
        [self.contentView addSubview:label];

        imageView = [UIImageView new];
        [self.contentView addSubview:imageView];

        _renderedMark = [self renderMark];
    }
    return self;
}

#pragma mark - Properties
- (void)setIsSelected:(BOOL)isSelected
{
    _isSelected = isSelected;
    self.imageView.image = (isSelected) ? _renderedMark : nil;

    [self setNeedsDisplay];
}

- (UIImage *)renderMark
{
    if(_renderedMark)
        return _renderedMark;

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(kMarkImageSize, NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(kMarkImageSize);

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIBezierPath *markCircle = [UIBezierPath bezierPathWithOvalInRect:kCircleRect];

    /* Background */
    CGContextSaveGState(ctx);
    {
        CGContextAddPath(ctx, markCircle.CGPath);
        CGContextSetFillColorWithColor(ctx, clearColorWithRGBHex(kMarkColor).CGColor);
        CGContextSetShadowWithColor(ctx, kShadowOffset, kShadowRadius, kShadowColor.CGColor );
        CGContextDrawPath(ctx, kCGPathFill);
    }
    CGContextRestoreGState(ctx);

    /* Overlay */
    CGContextSaveGState(ctx);
    {
        CGContextAddPath(ctx, markCircle.CGPath);
        CGContextClip(ctx);
        CGContextAddEllipseInRect(ctx, kCircleOverlayRect);
        CGContextSetFillColorWithColor(ctx, colorWithRGBHex(kMarkColor).CGColor);
        CGContextDrawPath(ctx, kCGPathFill);
    }
    CGContextRestoreGState(ctx);

    /* Stroke */
    CGContextSaveGState(ctx);
    {
        CGContextAddPath(ctx, markCircle.CGPath);
        CGContextSetLineWidth(ctx, kStrokeWidth);
        CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
        CGContextDrawPath(ctx, kCGPathStroke);
    }
    CGContextRestoreGState(ctx);

    /* Mark */
    CGContextSaveGState(ctx);
    {
        CGContextSetShadowWithColor(ctx, kMarkShadowOffset, .0, kMarkShadowColor.CGColor );
        CGContextMoveToPoint(ctx, kMarkBase.x, kMarkBase.y);
        CGContextAddLineToPoint(ctx, kMarkBase.x + kMarkHeight * sin(kMarkDegrees), kMarkBase.y + kMarkHeight * cos(kMarkDegrees));
        CGContextAddLineToPoint(ctx, kMarkDrawPoint.x, kMarkDrawPoint.y);
        CGContextSetLineWidth(ctx, kMarkWidth);
        CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
        CGContextStrokePath(ctx);
    }
    CGContextRestoreGState(ctx);

    UIImage *selectedMark = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return selectedMark;
}

@end

I would very much appreciate any help with this problem.

Upvotes: 0

Views: 420

Answers (3)

Satyaranjan
Satyaranjan

Reputation: 137

One can use [tableView reloadData] from orientations methods to resize height/width of cells. That can be done by setting a boolean as well

Upvotes: 0

Hetal Vora
Hetal Vora

Reputation: 3361

There are a few weird things in your code and I have a few points of advise:

  1. viewDidLoad must be called only (and by iOS not by you) when the view is loaded. Do not make calls to viewDidLoad again on rotation.
  2. The willRotateToInterfaceOrientation should also not be called manually by you. Its the OS that makes the call. My advise would be to get rid of the call to this method.

Try these, test and post what you observe on testing.

Upvotes: 1

Laszlo
Laszlo

Reputation: 2778

I use a lot of custom UITableViewCell like insert something like this:

if([selectedMarks containsObject:indexPath]){ // Or something like that
    CRTableViewCell *customCell = [CRTableViewCell new];
    customCell.customProperty = @"Custom";
    cell = customCell;
}

to -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

And no problem with resizing and rotating and interactions

Upvotes: 0

Related Questions