Подтвердить что ты не робот

Как сохранить круглый imageView круглый с использованием автоматического макета?

Как преобразовать прямоугольное изображение в круглое изображение, которое может сохранять форму в автоматическом макете без установки ограничений ширины и высоты? Таким образом, позволяя imageView определять его размер и размер больше и меньше по отношению к окружающим его объектам с ограничениями ведущего, конечного, верхнего и нижнего.

На днях я задал аналогичный вопрос, но думаю, что это может быть поставлено более сжатым способом. Спасибо!

РЕДАКТИРОВАТЬ

Хорошо, я начал, чтобы сделать это как можно проще. У меня есть вид под названием "Ячейка" и UIImageView с именем "собака" внутри ячейки, и это так. У меня больше нет "возможности одновременного удовлетворения ограничений" в консоли, всего два простых вида с использованием автоматического макета. Я все еще пытаюсь использовать этот код для округления UIImageView:

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

Вот настройка ограничения ячейки:

screenshot 1

Вот настройка ограничения pic профиля:

screenshot 2

Вот результат без кода, без округления, но красивый и квадратный:

screenshot 3

Вот результат с округлением кода:

screenshot 4

Это не имеет для меня никакого смысла, потому что без кода округления изображение квадратное, а с кодом - алмаз. Если он квадратный, это не кружок без проблем?

EDIT 2

Вот что происходит, когда я удаляю нижнее ограничение и добавляю множитель.637 для равной высоты для просмотра.

screenshot 5

4b9b3361

Ответ 1

К сожалению, вы не можете сделать это, используя cornerRadius и автозапуск - на CGLayer не влияет автоматическое отключение, поэтому любое изменение размера представления не изменит радиус, который был установлен один раз, поскольку вы заметили, круг потеряет свою форму.

Вы можете создать пользовательский подкласс UIImageView и переопределить layoutSubviews, чтобы установить cornerRadius каждый раз, когда изменяются границы изображения.

ИЗМЕНИТЬ

Пример может выглядеть примерно так:

class Foo: UIImageView {
    override func layoutSubviews() {
        super.layoutSubviews()

        let radius: CGFloat = self.bounds.size.width / 2.0

        self.layer.cornerRadius = radius
    }
}

И, очевидно, вам нужно будет ограничить ширину экземпляра Foobar равным высоте (для поддержания круга). Вероятно, вы также захотите установить Foobar экземпляр contentMode на UIViewContentMode.ScaleAspectFill, чтобы он знал, как рисовать изображение (это означает, что изображение может быть обрезано).

Ответ 2

Настройка радиуса в viewWillLayoutSubviews решит проблему

override func viewWillLayoutSubviews() {
  super.viewWillLayoutSubviews()
  profileImageView.layer.cornerRadius = profileImageView.frame.height / 2.0
}

Ответ 3

создайте новый интерфейс в файле .h, например

@interface CornerClip : UIImageView

@end

и реализация в файле .m, например

@implementation cornerClip


-(void)layoutSubviews
{
    [super layoutSubviews];

    CGFloat radius = self.bounds.size.width / 2.0;

    self.layer.cornerRadius = radius;

}

@end

теперь просто дайте классу "CornerClip" для вашего изображения. 100% работает... Наслаждайтесь

Ответ 4

Кажется, когда вы добавляете одно представление в качестве подзаголовка другого, то сетчатое представление не обязательно будет иметь ту же высоту, что и его супервизор. Вот в чем проблема. Решение заключается не в том, чтобы добавить изображение в качестве подзаголовка, а иметь его поверх фонового изображения. На изображении ниже я использую UILabel в качестве фона.

screenshot

Также в вашем случае, когда вы устанавливаете cornerRadius, используйте это: let radius: CGFloat = self.bounds.size.height / 2.0.

Ответ 5

Благодаря моему хакерскому решению вы получите гладкую анимацию радиуса радиуса наряду с изменением размера кадра.

Скажем, у вас есть ViewSubclass: UIView. Он должен содержать следующий код:

class ViewSubclass: UIView {
    var animationDuration : TimeInterval?
    let imageView = UIImageView()
    //some imageView setup code

    override func layoutSubviews() {
        super.layoutSubviews()

        if let duration = animationDuration {
            let anim = CABasicAnimation(keyPath: "cornerRadius")
            anim.fromValue = self.imageView.cornerRadius
            let radius = self.imageView.frame.size.width / 2
            anim.toValue = radius
            anim.duration = duration
            self.imageView.layer.cornerRadius = radius
            self.imageView.layer.add(anim, forKey: "cornerRadius")
        } else {
            imageView.cornerRadius = imageView.frame.size.width / 2
        }

        animationDuration = nil
    }
}

Затем вам нужно будет сделать это:

let duration = 0.4 //For example
instanceOfViewSubclass.animationDuration = duration
UIView.animate(withDuration: duration, animations: { 
    //Your animation
    instanceOfViewSubclass.layoutIfNeeded()
})

Это не красиво и может не работать для сложных мульти-анимаций, но отвечает на вопрос.

Ответ 6

У меня такая же проблема, и теперь я получаю то, что здесь произошло, надеюсь, что некоторые идеи помогут вам: между буксирами есть что-то другое:

  • ваш профильImageView в раскадровке
  • ваш профильImageView в viewDidLoad

размер связанного и фрейма отличается при viewDidLoad и в раскадровке, только потому, что размер представления изменяется для разных размеров устройства. Вы можете попробовать print(profileImageView.bounds.size) в viewDidLoad и viewDidAppear, вы найдете, что размер в viewDidLoad, который вы установили cornerRadius, не является реальным "рабочим" размером.

советы для вас: вы можете использовать subClass ImageView, чтобы избежать этого, или не использовать его в раскадровке,

Ответ 7

Если вы подклассифицировали UIImageView. Затем просто добавьте в него этот волшебный код.

Написано в: Swift 3

override func layoutSubviews() {
    super.layoutSubviews()
    if self.isCircular! {
        self.layer.cornerRadius = self.bounds.size.width * 0.50
    }
}

Ответ 8

Swift 4+ чистое решение на основе ответа омаралбека

import UIKit

extension UIImageView {

    func setRounded(borderWidth: CGFloat = 0.0, borderColor: UIColor = UIColor.clear) {
        layer.cornerRadius = frame.width / 2
        layer.masksToBounds = true
        layer.borderWidth = borderWidth
        layer.borderColor = borderColor.cgColor
    }
}

Использование примера в UIViewController

1. Просто округленный UIImageView

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        imageView.setRounded()
    }

2.Расширенный UIImageView с шириной и цветом границы

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        imageView.setRounded(borderWidth: 1.0, borderColor: UIColor.red)
    }

Ответ 9

Добавьте ограничение пропорций 1:1 к imageView, чтобы он оставался круглым, несмотря на любые изменения высоты или ширины.

Ответ 10

Легко сделать, создав IBOutlet для ограничения, которое необходимо изменить во время выполнения. Ниже приведен код:

  • Создайте IBOutlet для ограничения, которое необходимо изменить во время выполнения.

    @IBOutlet var widthConstraint: NSLayoutConstraint!
    
  • Добавьте ниже код в viewDidLoad():

    self.widthConstraint.constant = imageWidthConstraintConstant()
    

Ниже функция определяет, для типов устройств соответственно изменяют ограничение ширины.

func imageWidthConstraintConstant() -> CGFloat {

    switch(self.screenWidth()) {

    case 375:
        return 100

    case 414:
        return 120

    case 320:
        return 77

    default:
        return 77
    }
}