2012-07-17 58 views
1

我将UIButton添加为子视图后遇到问题。当我尝试调整视图上的按钮位置时,我始终只用第一个按钮添加UIView而不是UIButton。当我使用isKindOfClass时,其余的返回为UIButton。这里是一个代码片段如下添加到子视图后,UIButton返回为UIView?

首先,我从viewDidload调用createTiles方法将按钮添加为子视图,然后通过调用adustLandscapeTiles/Portrait方法检测设备方向后调整按钮布局。

我不确定为什么会发生任何想法? ?

// Adding buttons to view 
- (void)createTiles 
{  
    for(int i=0;i<[self.contentList count];i++) 
    { 
     UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [button addTarget:self action:@selector(buttonSelection:)forControlEvents:UIControlEventTouchDown]; 
     [button setTitle:[ [contentList objectAtIndex:i] valueForKey:@"nameKey"] forState:UIControlStateNormal]; 
     button.tag=i; 

     [self.view insertSubview:button atIndex:0]; 
     NSLog(@"adding %i %@",i , [ [contentList objectAtIndex:i] valueForKey:@"nameKey"]); 
     [button release]; 

    } 
    } 

- (void)adustLandscapeTiles 
{ 
    for (int row = 0; row < Portrait_TILE_ROWS; ++row) 
    { 
     for (int col = 0; col < Portrait_TILE_COLUMNS; ++col) 
     { 
      int index = (row * Portrait_TILE_COLUMNS) + col;  
      CGRect frame = CGRectMake(LandScape_TILE_MARGIN + col * (LandScape_TILE_MARGIN + LandScape_TILE_WIDTH), 
            LandScape_TILE_MARGIN + row * (LandScape_TILE_MARGIN + LandScape_TILE_HEIGHT), 
            LandScape_TILE_WIDTH, LandScape_TILE_HEIGHT); 
    /// check subview is a button  
    NSLog(@"index: %i tag : %i Is of type UIButton?: %@",index,[[self.view viewWithTag:index] tag], ([ [self.view viewWithTag:index] isKindOfClass: [UIButton class]])? @"Yes" : @"No"); 

     /// Only the first button added with tag zero return UView instead of UIButton ?? 
      UIButton *tmb= (UIButton *)[self.view viewWithTag:index]; 
      if([tmb isKindOfClass:[UIButton class]]) //isKindOfClass 
      { 
       [ [self.view viewWithTag:index] setFrame:frame]; 

      } 

     } 
    } 

} 

回答

1

当我加入了更强大的解决您的问题,我注意到你在释放button。你不应该打电话[button release]你不拥有它!但这不是你唯一的问题...

如果你没有给UIView分配一个标签,它会有一个零标签,所以如果你的视图有一些你没有给你分配标签的其他子视图可能是得到其中一个。尝试添加一些偏移将自己的代码,例如:

// Somewhere early in your .m file 
const NSInteger kButtonTagOffset 256 

// In your createTiles 
button.tag = (kButtonTagOffset + i); 

显然,你需要添加,当您找回您的瓷砖也该偏移。

话虽如此,当前的方法是什么一个更有经验的程序员可能调用脆弱如果有人曾经子类类或者即使你编辑了一段时间以后,你可以分配发生冲突的代码,并导致一些问题。您可能会考虑更多稳健的解决方案。

因为你真正想要做的就是保持按钮的数组,你可以通过索引访问,为什么不做到这一点,而不依赖于标签?

因此在您的UIViewController中添加一个NSMutableArray来保存您的按钮。

// In your .h or with private methods: 
@property (nonatomic, retain) NSMutableArray* buttons; 

// At the top of your @implementation 
@synthesize buttons; 

// A modified createTiles 
// Adding buttons to view 
- (void)createTiles 
{  
    self.buttons = nil; /* in case viewDidUnload id not do this. */ 
    self.buttons = [[[NSMutableArray alloc] init] autorelease]; 
    for(int i=0;i<[self.contentList count];i++) 
    { 
     UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [button addTarget:self  
        action:@selector(buttonSelection:) 
     forControlEvents:UIControlEventTouchDown]; 
     [button setTitle:[[contentList objectAtIndex:i] valueForKey:@"nameKey"] 
       forState:UIControlStateNormal]; 

     [self.view insertSubview:button atIndex:0]; 
     NSLog(@"adding %i %@", i, 
         [[contentList objectAtIndex:i] valueForKey:@"nameKey"]); 
     [self.buttons insertObject:button atIndex:0]; 
    } 
} 

- (void)adustLandscapeTiles 
{ 
    for (int row = 0; row < Portrait_TILE_ROWS; ++row) 
    { 
     for (int col = 0; col < Portrait_TILE_COLUMNS; ++col) 
     { 
      int index = (row * Portrait_TILE_COLUMNS) + col;  
      UIView* buttonView = [self.buttons objectAtIndex:index]; 

      CGRect frame = CGRectMake(LandScape_TILE_MARGIN + col *  
           (LandScape_TILE_MARGIN + LandScape_TILE_WIDTH), 
           LandScape_TILE_MARGIN + row *  
           (LandScape_TILE_MARGIN + LandScape_TILE_HEIGHT), 
           LandScape_TILE_WIDTH, 
           LandScape_TILE_HEIGHT); 
      // check subview is a button  
      NSLog(@"index: %i Is of type UIButton?: %@", index, 
        ([ [buttonView viewWithTag:index] isKindOfClass: [UIButton class]])? 
         @"Yes" : @"No"); 

      UIButton *tmb= (UIButton *)buttonView; 
      if([tmb isKindOfClass:[UIButton class]]) //isKindOfClass 
      { 
       [buttonView setFrame:frame]; 
      } 
     } 
    } 
} 
+0

感谢IDZ,当我试图改变在Interface Builder的观点是没有工作的标记值,但与你的偏移建议的工作完美...谢谢 – user519274 2012-07-17 14:09:53

+0

纠正我,如果我错了,也不会该语句[self.view insertSubview:按钮atIndex:0]增加按钮的保留计数与[self.buttons insertObject:button atIndex:0]相同? 。您的方法肯定会更易于维护,而我最初将执行该方法,但我担心增加按钮的保留数量? – user519274 2012-07-17 16:56:12

+0

保留两次只要释放两次就没有问题。因此,在您的情况下,要成为一名优秀的内存管理公民,您需要确保在'viewDidUnload'中设置'self.buttons = nil'并删除所有子视图。您应该已经在执行删除所有子视图步骤,因为您提到您正在从'viewDidLoad'调用'createTiles'。规则是你应该在'viewDidUnload'和'dealloc'中释放* viewDidLoad中创建的任何内容。 – idz 2012-07-17 19:02:25

相关问题