Возникли проблемы при получении UIView sizeToFit, чтобы сделать что-нибудь значимое - PullRequest
35 голосов
/ 16 октября 2010

Когда я добавляю подпредставление к UIView или когда я изменяю размер существующего подпредставления, я ожидаю, что [view sizeToFit] и [view sizeThatFits] отразят это изменение.Однако мой опыт показывает, что sizeToFit ничего не делает, а sizeThatFits возвращает одно и то же значение до и после изменения.

Мой тестовый проект имеет одно представление, содержащее одну кнопку.Нажатие на кнопку добавляет еще одну кнопку к представлению, а затем вызывает sizeToFit на содержащем представлении.Границы представления выводятся на консоль до и после добавления подпредставления.

- (void) logSizes {
 NSLog(@"theView.bounds: %@", NSStringFromCGRect(theView.bounds));
 NSLog(@"theView.sizeThatFits: %@", NSStringFromCGSize([theView sizeThatFits:CGSizeZero])); 
}

- (void) buttonTouched { 
 [self logSizes];
 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 btn.frame = CGRectMake(10.0f, 100.0f, 400.0f, 600.0f);
 [theView addSubview:btn];
 [theView sizeToFit];
 [self performSelector:@selector(logSizes) withObject:nil afterDelay:1.0];
}

И вывод:

2010-10-15 15:40:42.359 SizeToFit[14953:207] theView.bounds: {{0, 0}, {322, 240}}
2010-10-15 15:40:42.387 SizeToFit[14953:207] theView.sizeThatFits: {322, 240}
2010-10-15 15:40:43.389 SizeToFit[14953:207] theView.bounds: {{0, 0}, {322, 240}}
2010-10-15 15:40:43.391 SizeToFit[14953:207] theView.sizeThatFits: {322, 240}

Я должен что-то здесь упустить.

Спасибо.

Ответы [ 4 ]

51 голосов
/ 16 октября 2010

Документация достаточно ясна по этому вопросу.-sizeToFit в значительной степени вызывает -sizeThatFits: (возможно, с текущим размером представления в качестве аргумента), а реализация по умолчанию -sizeThatFits: почти ничего не делает (просто возвращает свой аргумент).

Некоторые подклассы UIView переопределяют-sizeThatFits: чтобы сделать что-то более полезное (например, UILabel).Если вы хотите любую другую функциональность (например, изменение размера представления, чтобы соответствовать его подпредставлениям), вы должны создать подкласс UIView и переопределить -sizeThatFits:.

3 голосов
/ 16 апреля 2016

Если вы не переопределите UIView, вы можете просто использовать расширение.

Swift:

extension UIView {

    func sizeToFitCustom () {
        var size = CGSize(width: 0, height: 0)
        for view in self.subviews {
            let frame = view.frame
            let newW = frame.origin.x + frame.width
            let newH = frame.origin.y + frame.height
            if newW > size.width {
                size.width = newW
            }
            if newH > size.height {
                size.height = newH
            }
        }
        self.frame.size = size
    }

}

Тот же код, но в 3 раза быстрее:

extension UIView {
    final func sizeToFitCustom() {
        var w: CGFloat = 0,
            h: CGFloat = 0
        for view in subviews {
            if view.frame.origin.x + view.frame.width > w { w = view.frame.origin.x + view.frame.width }
            if view.frame.origin.y + view.frame.height > h { h = view.frame.origin.y + view.frame.height }
        }
        frame.size = CGSize(width: w, height: h)
    }
}
0 голосов
/ 10 октября 2014
        self.errorMessageLabel.text = someNewMessage;

    // We don't know how long the given error message might be, so let's resize the label + containing view accordingly
    CGFloat heightBeforeResize = self.errorMessageLabel.frame.size.height;

    [self.errorMessageLabel sizeToFit];

    CGFloat differenceInHeightAfterResize = self.errorMessageLabel.frame.size.height - heightBeforeResize;

    self.errorViewHeightContstraint.constant = kErrorViewHeightConstraintConstant + differenceInHeightAfterResize;

Это сработало для меня.

0 голосов
/ 21 января 2013

Вы можете сделать что-то подобное, используя только IB (xcode 4.5):

  1. Нажмите на UIView
  2. в Инспекторе размеров, перетащите content hugging на 1 (обапо горизонтали и вертикали)
  3. перетащите compression resistance на 1000 (для обоих)
  4. под UIView constraints, нажмите Width и измените priority на 250
  5. Сделайте то же самое для высоты
  6. . Вы можете использовать UIView inset для управления отступами слева / справа / сверху / снизу
...