将子视图添加到自定义视图时出现问题

时间:2013-01-12 21:08:46

标签: ios6

我正在尝试按this answer创建一个分页滚动视图,显示下一张和上一张图像。

我创建了一个自定义的UIView类,并将UIScrollView添加为子视图。我有两个问题。

  1. 我希望视图与IB一起工作,所以我实现了initWithCoder并尝试在调用超类initWithCoder之后将帧传递给我的init。但框架的宽度和高度始终为0。
  2. 为了解决这个问题,我在initView方法中使用了屏幕宽度。但是我的滚动视图(或者更确切地说是其中的图像)没有显示。我改变了自定义视图(红色)和滚动视图(蓝色)的背景颜色,我看到的只是红色背景。我已经检查了scrollview的frame rect,看起来很合理(59,0,201,135),所以我不确定为什么我无法显示scrollview。
  3. 任何想法都会受到赞赏。

    ModeSelectView.m

    #import "ModeSelectView.h"
    
    @implementation ModeSelectView
    
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            [self initView:frame];
        }
        return self;
    }
    
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        self = [super initWithCoder:(aDecoder)];
        if (self) {
            CGRect frame = self.frame;
            [self initView:self.frame];
        }
        return self;
    }
    
    - (void)initView:(CGRect)frame
    {
        // Initialization code
        // Create an array of images for the different modes
        UIImage *imgTowerOnlyMode = [UIImage imageNamed:@"tower_only_mode_icon.png"];
        UIImage *imgLocalMode = [UIImage imageNamed:@"local_mode_icon.png"];
        UIImage *imgHowToPlay = [UIImage imageNamed:@"how_to_play_icon.png"];
        NSArray *modeSelectIcons = @[imgTowerOnlyMode, imgLocalMode, imgHowToPlay];
    
        int iconSize = 115;
        // Center to center icon spacing
        int viewSpacing = 115 * 1.75;
        int frameWidth = 2*viewSpacing;
        int contentWidth = 4*frameWidth;
        int pageWidth = viewSpacing;
        int verticalPadding = 10;
        int pageHeight = iconSize + 2*verticalPadding;
            //int viewWidth = frame.size.width;
        int viewWidth = [[UIScreen mainScreen] applicationFrame].size.width;
        int scrollViewX = (viewWidth - pageWidth)/2;
    
        // Create the scrollview, setting it to be page size in width the icon height plus padding
        CGRect scrollViewFrame = CGRectMake(scrollViewX, 0, pageWidth, pageHeight);
        self.scrollModeSelect = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
    
        // Now iterate over the array creating a view for each
        // The first view will be offset in X to allow it to be
        // centered in the page
        int imageOffset = (frameWidth-iconSize)/2;
        for (int i = 0; i < [modeSelectIcons count]; ++i) {
            // Get the origin x value for the image view within the scroll view
            int viewOriginX = i*frameWidth + imageOffset;
    
            // Initialize the image view
            UIImageView *ivModeSelect = [[UIImageView alloc]
            initWithFrame:CGRectMake(viewOriginX , verticalPadding/2,
                                     iconSize, iconSize)];
    
            // Set the image
            ivModeSelect.image = (UIImage *)modeSelectIcons[i];
    
            // Tell the parent view to scale the iamge, preserving aspect ratio, to
            // fit the parent view.
            ivModeSelect.contentMode = UIViewContentModeScaleAspectFit;
    
            // Add the image view to the scroll view
            [self.scrollModeSelect addSubview:ivModeSelect];
        }
    
        [self.scrollModeSelect setContentSize:CGSizeMake(contentWidth, pageHeight)];
        // Turn off clipping so we can see the adjacent icons
        [self.scrollModeSelect setClipsToBounds:FALSE];
    
        // Add the scrollview as a subview
        [self addSubview:self.scrollModeSelect];
    
        [self.scrollModeSelect setBackgroundColor:[UIColor blueColor]];
        [self setBackgroundColor:[UIColor redColor]];
    }
    
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect
    {
        // Drawing code
    }
    */
    
    @end
    

1 个答案:

答案 0 :(得分:0)

事实证明,您无法在initWith方法中进行任何视图大小调整,因为尚未确定应用程序框架。因此,要执行此操作,您需要使用默认大小在视图层次结构中设置视图。然后,您需要覆盖layoutSubviews来进行大小调整。在layoutSubviews中,您可以使用self.frame访问视图框。所以这里是与上面相同的代码,但是使用layoutSubviews。

- (void)initView:(CGRect)frame
{
    // Initialization code
    self.ivModeSelectArray = [[NSMutableArray alloc] init];

    // Create an array of images for the different modes
    UIImage *imgTowerOnlyMode = [UIImage imageNamed:@"tower_only_mode_icon.png"];
    UIImage *imgLocalMode = [UIImage imageNamed:@"local_mode_icon.png"];
    UIImage *imgHowToPlay = [UIImage imageNamed:@"how_to_play_icon.png"];
    NSArray *modeSelectIcons = @[imgTowerOnlyMode, imgLocalMode, imgHowToPlay];

    // Create the scrollview, initially setting it to 0 size.  We'll resize it
    // in layoutSubviews
    CGRect scrollViewFrame = CGRectMake(0,0,200,110);
    self.scrollModeSelect = [[UIScrollView alloc] initWithFrame:scrollViewFrame];

    // Now iterate over the array creating a view for each, intially set to 0
    // size.  We'll resize them and reposition them in layoutSubviews
    for (int i = 0; i < [modeSelectIcons count]; ++i) {
        UIImageView *ivModeSelect =
                 [self addModeIcon:[modeSelectIcons objectAtIndex:i]];

        // Add the image view to the scroll view
        [self.scrollModeSelect addSubview:ivModeSelect];
    }

    // Turn off clipping so we can see the adjacent icons
    [self.scrollModeSelect setClipsToBounds:FALSE];

    // Turn on paging
    [self.scrollModeSelect setPagingEnabled:TRUE];

    // Add the scrollview as a subview
    [self addSubview:self.scrollModeSelect];

//    self.scrollModeSelect.backgroundColor = [UIColor blueColor];
//    self.backgroundColor = [UIColor redColor];
}

- (void)layoutSubviews
{
    int iconSize = 115;
    // Center to center icon spacing
    CGFloat viewSpacing = 115 * 1.4;
    int frameWidth = viewSpacing;
    int contentWidth = 4*frameWidth;
    int pageWidth = viewSpacing;
    int verticalPadding = 10;
    int pageHeight = iconSize + 2*verticalPadding;
    int viewWidth = self.frame.size.width;
    int scrollViewX = (viewWidth - frameWidth)/2;

    // Now iterate over the array configuring the size and offset for each view
    // The first view will be offset in X to allow it to be centered in the page
    int imageOffset = (frameWidth-iconSize)/2;
    for (int i = 0; i < [self.ivModeSelectArray count]; ++i) {
        // Get the origin x value for the image view within the scroll view
        int viewOriginX = i*viewSpacing + imageOffset;

        // Size the image view
        UIImageView *ivModeSelect = [self.ivModeSelectArray objectAtIndex:i];
        [ivModeSelect setFrame:CGRectMake(viewOriginX , verticalPadding/2,
                                          iconSize, iconSize)];

    }

    [self.scrollModeSelect setFrame:CGRectMake(scrollViewX, 0,
                                               pageWidth,pageHeight)];
    [self.scrollModeSelect setContentSize:CGSizeMake(contentWidth, pageHeight)];
}