0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UICollisionBehaviorでサイズ勝手に変更される問題

Last updated at Posted at 2015-05-07

ここで紹介している問題はバグではなく、UICollisionBehaviorの仕様です。

https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UICollisionBehavior_Class/index.html より

IMPORTANT

When setting the initial position for a dynamic item, you must ensure that its bounds do not intersect any collision boundaries. The animation behavior for such a misplaced item is undefined.

要するに考えずに重ねて初期配置すると変なことになるよ。
ということです。

再現コード

ViewController.m
@interface ViewController (){
    UIDynamicAnimator *animator;
    UICollisionBehavior *collisionBehavior;
    NSMutableArray*vs;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    vs = [NSMutableArray array];
    animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    collisionBehavior = [UICollisionBehavior new];
    collisionBehavior.translatesReferenceBoundsIntoBoundary  = true;
    [animator addBehavior:collisionBehavior];
    
    UITapGestureRecognizer*t = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    [self.view addGestureRecognizer:t];
}

- (void)tap{
    UIView*v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    v.backgroundColor = [UIColor redColor];
    [self.view addSubview:v];
    [vs addObject:v];
    for (id o in collisionBehavior.items) {
        [collisionBehavior removeItem:o];
    }
    int index = 0;
    for (UIView*view in vs) {
        view.frame = CGRectMake(0,100*index, 100,100);
        [collisionBehavior addItem:view];
        if (view.bounds.size.height!=view.bounds.size.width) {
            view.backgroundColor = [UIColor blueColor];
            NSLog(@"size w=%f : h=%f",view.bounds.size.width,view.bounds.size.height);
        }
        index++;
    }
}

@end

タップするたびに100100の四角を画面左端に並べていくコードです。
ただし、translatesReferenceBoundsIntoBoundaryが設定してあるので画面をはみ出すと初期位置が画面右下のビューと被った状態でコリジョンビヘイビアに登録されます。
上記のコードでは縦横100
100が崩れると青くなるように書かれています。

iOS Simulator Screen Shot May 8, 27 Heisei, 3.34.18 AM.png

iOS Simulator Screen Shot May 8, 27 Heisei, 3.34.20 AM.png

iOS Simulator Screen Shot May 8, 27 Heisei, 3.34.21 AM.png

再現出来ました。

frameのsizeを弄っていないのにビューのサイズが変わってしまったのを確認出来たかと思います。

なかなかエグい仕様なので、ごちゃごちゃするUIを作る場合には注意です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?