ClipsToBounds заставляет UIImage не отображаться в iOS10 и XCode 8

Я переключил свой проект на новые бета-версии iOS 10 и XCode 8. Во всех трех областях моего приложения, где я использую:

imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true

Связанные изображения вообще не отображаются. Я попытался очистить проект, а также папку сборки, перезапустить устройство, попробовать различные симуляторы, повторно добавить изображениеView, программно установив связанный UIImage вместо того, чтобы выбрать один из активов.

Удаление строки clipsToBounds показывает прямоугольное изображение независимо от того, является ли masksToBounds true или false. Как сделать круговое изображение в XCode8/iOS10?

Изменить: проект Swift 2.x и еще не обновлен до синтаксиса Swift 3.0.

Ответ 2

Эта проблема также произошла со мной.

Я переместил этот код imageView.layer.cornerRadius = imageView.frame.size.width/2 с - (void)awakeFromNib на - (void)drawRect:(CGRect)rect, и эта проблема исчезла.

Мой образ изображения имеет размер автоопределения. Я думаю, что высота и ширина не решаются при пробуждении от nib на iOS 10.

Ответ 3

Это похоже на то, что это может быть связано с новой ошибкой с iOS 10 и Xcode 8, где представления инициализируются размером 1000x1000 и при попытке установить радиус угла до половины вашего кадра, вместо этого он устанавливает значение 500. Это описано далее в этом вопросе здесь: Так как Xcode 8 и iOS10, представления не отсортированы должным образом в viewDidLayoutSubviews. Моя причина думать об этом - это исправление проблемы 1000x1000, чтобы вызвать вызовы макета, прежде чем делать что-либо, требующее размеров для чего-то, что было построено на построителе интерфейса.

Ответ 4

У меня была та же проблема. Не показывать по телефону, но идеально подходит для отладки раскадровки и UI. Он также работал, когда я запускал проект "Открывается с Xcode 7" вместо 8, но не был удовлетворительным решением. Поэтому я выкопал и выяснил проблему. Проблема заключалась в том, что класс выглядит следующим образом:

@IBDesignable public class MyButton: UIButton {

   @IBInspectable var styleName: String = "" {
        didSet {
            switch styleName {
            case "RoundedLight":
                tintColor = UIColor.lightPinkColor()
                layer.borderColor = UIColor.whiteColor().CGColor
                layer.borderWidth = 1
                layer.masksToBounds = true
            default:
                break
            }
        }
    }

    override public func layoutSubviews() {
        super.layoutSubviews()

        switch styleName {
            case "RoundedLight":
                layer.cornerRadius = frame.height / 2
            default:
                break
        }
    }
}

Я изменил его на это, и теперь он работает:

@IBDesignable public class MyButton: UIButton {

   @IBInspectable var styleName: String = "" {
        didSet {
            layoutIfNeeded()
        }
    }

    override public func layoutSubviews() {
        super.layoutSubviews()

        switch styleName {
        case "RoundedLight":
            tintColor = UIColor.lightPinkColor()
            layer.borderColor = UIColor.whiteColor().CGColor
            layer.borderWidth = 1
            layer.cornerRadius = frame.height / 2
            layer.masksToBounds = true
        default:
            break
        }
    }
}

Обратите внимание, что ни одно из вышеперечисленных не работало для меня, и я имею в виду:

  • Вызов layoutIfNeeded в layoutSubviews()
  • Вызов layoutIfNeeded в awakeFromNib моей кнопки (или моей ячейки, содержащей кнопку)
  • Вызов layoutIfNeeded в layoutSubview моей ячейки
  • Вызов contentView.layoutIfNeeded() в awakeFromNib моей ячейки
  • Вызов view.layoutIfNeeded() в моем контроллере

Ответ 5

У меня был ImageView, который был полностью круглым. Ниже приведен код:

//MARK:- Misc functions
func setProfileImage() {
    imgProfile.layer.masksToBounds = false
    imgProfile.layer.cornerRadius = imgProfile.frame.size.height/2
    imgProfile.clipsToBounds = true
    imgProfile.contentMode = UIViewContentMode.ScaleToFill
} 

Это отлично работает в iOS 9. Однако in iOS 10 Xcode 8 the ImageView disappears. После отладки найдено, что ClipsToBound является виновником.

Итак, помещенный код в viewDidLayoutSubviews() разрешил проблему.

override func viewDidLayoutSubviews() {
    setProfileImage()
}

Вы также можете использовать self.view.layoutIfNeeded()

Ответ 6

Это может быть проблема с макетом. Установка clipToBounds на false показала бы изображение, даже если его размер равен нулю. Вы можете распечатать frame ваших изображений?

Если вы установите свойства cornerRadius и clipToBounds в viewDidLoad, попробуйте сделать это в viewDidLayoutSubviews().

Вы также можете попробовать вызвать self.view.layoutIfNeeded().

Ответ 7

Используя obj-c, мне удалось работать с синтаксисом от viewDidLoad до viewDidLayoutSubviews.

Ответ 8

Я просто применил угловое округление, подобное этому

@implementation RoundImageView

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
        [self addObserver:self
               forKeyPath:@"bounds"
                  options:NSKeyValueObservingOptionNew
                  context:(__bridge void * _Nullable)(self)];
    }
    return self;
}

-(void)dealloc
{
    [self removeObserver:self
              forKeyPath:@"bounds"
                 context:(__bridge void * _Nullable)(self)];
}

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSString *,id> *)change
                      context:(void *)context
{
    if(context == (__bridge void * _Nullable)(self) && object == self && [keyPath isEqualToString:@"bounds"])
    {
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
    }
}

@end

поэтому у меня всегда есть закругленные углы. И у меня не возникало проблем с обновлением до iOS10 и XCode8

Ответ 9

Я думаю, что проблема возникает из-за того, что мы устанавливаем круглый угол и подзаголовки клипов, как сказал @Pranoy C.

Я решил проблемы, используя layoutIfNeeded для ячейки tableview, отображающей изображение профиля пользователя. Я хочу, чтобы изображение было круглым углом.

Код выглядит следующим образом:   - (void) awakeFromNib {   [super awakeFromNib];   [self layoutIfNeeded];

[self.inputIndicator_imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.profile_pic_edit_imageView.layer.cornerRadius = self.profile_pic_edit_imageView.frame.size.width/2;
self.profile_pic_edit_imageView.layer.borderWidth = 1.0;
self.profile_pic_edit_imageView.layer.borderColor = GRAY_COLOR_SUPER_LIGHT.CGColor;
self.profile_pic_edit_imageView.clipsToBounds = YES;}

Ответ 10

Вы должны вызвать layoutSubviews() на главном экране перед вызовом imageView.frame.size.width

[self.view layoutSubviews];
imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true