views:

55

answers:

2

The UISwitch on my device: Switch Image with the bottom pixels cut off

The UISwitch on the simulator: Good UISwitch

As you can see, the bottom pixels are cut off on the device, but not on the simulator. I have tried just about everything I can think of, but nothing has fixed the problem.

Some of the things I've tried:

  • Changing the UISwitch's frame's height
  • Changing the UICell's height
  • Changing the UICell's contentView's height
  • Adding the UISwitch to the UICell rather than the UICell's contentView

Here is the relevant code:
This is in the viewDidLoad of the uiTableViewController:

UISwitch *sw =  [[UISwitch alloc] init];
self.contactedSwitch = sw;
[sw release];
self.contactedSwitch = [UISwitch switchWithLeftText:@"YES" andRight:@"NO"];
self.contactedSwitch.center = CGPointMake(230, 22);
self.contactedSwitch.on = [self.contact.contacted boolValue];

This is where the switchWithLeftText:andRight method comes from:

#import "UISwitch-Extended.h"

#define TAG_OFFSET  900

@implementation UISwitch (tagged)
- (void) spelunkAndTag: (UIView *) aView withCount:(int *) count
{
    for (UIView *subview in [aView subviews])
    {
        if ([subview isKindOfClass:[UILabel class]])
        {
            *count += 1;
            [subview setTag:(TAG_OFFSET + *count)];
        }
        else 
            [self spelunkAndTag:subview withCount:count];
    }
}

- (UILabel *) label1 
{ 
    return (UILabel *) [self viewWithTag:TAG_OFFSET + 1]; 
}

- (UILabel *) label2 
{ 
    return (UILabel *) [self viewWithTag:TAG_OFFSET + 2]; 
}

+ (UISwitch *) switchWithLeftText: (NSString *) tag1 andRight: (NSString *) tag2
{
    UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 94, 27)];

    int labelCount = 0;
    [switchView spelunkAndTag:switchView withCount:&labelCount];

    if (labelCount == 2)
    {
        [switchView.label1 setText:tag1];
        [switchView.label2 setText:tag2];
    }

    return [switchView autorelease];
}

@end

This is where I add the UISwitch to my tableviewcell:

[[contactedCell contentView] addSubview:self.contactedSwitch];

Thanks so much!

[Update] I thought the tableviewcell's might be the problem, so I added these UISwitches to a regular UIView to see how they looked. I have the exact same problem where they look alright in the simulator and the bottom is chopped in the device. So bizarre!

A: 

Never figured out exactly what was wrong, but I ended up creating the UISwitches in IB and got it to work beautifully that way. Very weird that it works in IB and not programmatically when I am basically doing the exact same thing.

Gorgando
+1  A: 

I had the same problem when programatically creating a UISwitch and changing its frame's origin- it turned out to be a half-pixel issue.

A key to noticing half-pixel bugs is: do the unwanted artifacts appear differently on the simulator vs device?

Your solution of placing the UISwitch with Interface Builder fixes this- you can also make sure to floor() your new coordinates if you are setting the UISwitch's frame's origin x/y.

UISwitch *mySwitch = [[UISwitch alloc] initWithFrame(CGRectZero)];
CGRect switchFrame = mySwitch.frame;  
// move frame up without pixel fractions
switchFrame.origin.y = floor((cell.contentView.frame.size.height - switchFrame.size.height) / 2); 
mySwitch.frame = switchFrame;
[cell.contentView addSubview:mySwitch];

In the original poster's case, the height of a uiswitch is an odd number (27 pixels), so setting the center to 22 splits the height into 13.5. The UISwitch's origin's y coordinate becomes 22-13.5 = 8.5 pixels. Either don't move a UISwitch by setting its center, or floor the coordinate, or use a fraction in the call to CGPointMake(230,22.5).

Another way to track this type of bug is to grep through Interface Builder looking for ".5" coordinates. I have found that sometimes over-tweaking the placement of UI elements in Interface Builder introduces this bug.

mr_marc