1

サブビューとして追加した後、UIButton へのアクセスに問題があります。ビューのボタンの位置を調整しようとすると、追加した最初のボタンだけで UIButton の代わりに UIView が常に取得されます。isKindOfClassを使用すると、残りはUIButtonとして返されます。これは次のようなコードスニペットです

まず、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];

            }

        }
    }

}
4

1 に答える 1

1

私があなたの問題にもっと頑強な解決策を追加している間、私はあなたが過剰に解放していることに気づきましたbutton。あなたはそれを所有していないと呼ぶべきではありませ[button release]ん!しかし、それだけが問題ではありません...

タグを割り当てない場合UIView、タグはゼロになります。したがって、タグを割り当てていない他のサブビューがビューにある場合は、それらの1つを取得している可能性があります。タグにオフセットを追加してみてください。次に例を示します。

// 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];
            }
        }
    }
}
于 2012-07-17T05:31:01.710 に答える