Есть ли событие изменения размера UIView?

У меня есть представление, в котором есть строки и столбцы изображений.

Если это представление изменено, мне нужно изменить порядок изображений.

Это представление является подзором другого представления, которое изменяется.

Есть ли способ определить, когда изменяется этот вид?

Ответ 1

Как сказал Ули ниже, правильный способ сделать это переопределить layoutSubviews и разместить там изображения.

Если по какой-то причине вы не можете подклассифицировать и переопределить layoutSubviews, то наблюдение bounds должно работать, даже если оно грязно. Хуже того, существует риск наблюдать - Apple не гарантирует работу KVO на классах UIKit. Прочитайте обсуждение с инженером Apple здесь: Когда вызывается связанный объект?

оригинальный ответ:

Вы можете использовать наблюдение за ключом:

[yourView addObserver:self forKeyPath:@"bounds" options:0 context:nil];

и реализовать:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == yourView && [keyPath isEqualToString:@"bounds"]) {
        // do your stuff, or better schedule to run later using performSelector:withObject:afterDuration:
    }
}

Ответ 2

В Swift вы можете:

override var bounds: CGRect {
    didSet {
        // Do stuff here
    }
}

Ответ 3

Создайте подкласс UIView и переопределите layoutSubviews

Ответ 4

Вы можете создать подкласс UIView и переопределить

setFrame: (CGRect) кадр

метод. Это метод, вызываемый при изменении кадра (т.е. Размера) вида. Сделайте что-то вроде этого:

- (void) setFrame:(CGRect)frame
{
  // Call the parent class to move the view
  [super setFrame:frame];

  // Do your custom code here.
}

Ответ 5

Довольно старый, но все же хороший вопрос. В образце кода Apple и в некоторых из их частных подклассов UIView они переопределяют setBounds примерно так:

-(void)setBounds:(CGRect)newBounds {
    BOOL const isResize = !CGSizeEqualToSize(newBounds.size, self.bounds.size);
    if (isResize) [self prepareToResizeTo:newBounds.size]; // probably saves 
    [super setBounds:newBounds];
    if (isResize) [self recoverFromResizing];
}

Переопределение setFrame: НЕ является хорошей идеей. frame выводится из center, bounds и transform, поэтому iOS не обязательно вызовет setFrame:.

Ответ 6

Swift 4 keypath KVO - это то, как я обнаруживаю авторотирование и перемещение на панель iPad. Должно работать любое представление. Пришлось наблюдать слой UIView.

private var observer: NSKeyValueObservation?

override func viewDidLoad() {
    super.viewDidLoad()
    observer = view.layer.observe(\.bounds) { object, _ in
        print(object.bounds)
    }
    // ...
}
override func viewWillDisappear(_ animated: Bool) {
    observer?.invalidate()
    //...
}

Ответ 7

Если вы находитесь в экземпляре UIViewController, переопределение viewDidLayoutSubviews делает трюк.

override func viewDidLayoutSubviews() {
    // update subviews
}