2015-09-02 3 views
28

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

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

EDIT

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

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

Здесь установки ячейки ограничения:

screenshot 1

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

screenshot 2

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

screenshot 3

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

screenshot 4

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

EDIT 2

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

screenshot 5

+0

Как вы в настоящее время делает вид изображения раунд? –

+0

@GavinHope Я вызываю его в ячейку в tableviewcontroller и используя: cell.ProfileImageView.layer.cornerRadius = cell.ProfileImageView.frame.size.width/2 cell.ProfileImageView.clipsToBounds = true – CHM

+0

Если ваше изображение было Ширина! = Высота, то вы можете найти решение здесь: http://stackoverflow.com/questions/29685055/ios-frame-size-width-2-doesnt-produce-a-circle-on-every-device – lee

ответ

-1

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

+0

Привет @petahchristian Я блокирую соотношение 1: 1, а также используя верхние, ведущие, конечные и нижние ограничения, но когда я уменьшаю или уменьшаю, я теряю идеальный круг. Когда я иду больше, я получаю продолговатый овал и меньше, больше из формы бриллианта. – CHM

+1

Вы получаете «Невозможно одновременно удовлетворить ограничения» в консоли? Если у вас есть верхние, ведущие, конечные и нижние ограничения, чем те ограничения, которые можно было бы вытащить или надавить на ваш образ, вы можете ограничить ограничение пропорций для торможения. –

+0

@ CHM Да. Как заметил Рандел, вы уже сдерживали изображение. Вы не можете иметь его размер в 4 направлениях, а также оставаться круговым. –

49

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

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

EDIT

Примером может выглядеть следующим образом:

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

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

     self.layer.cornerRadius = radius 
    } 
} 

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

+0

Hi @Rupert благодарит за информацию! Я просто мокрыю от Свифта.Это звучит довольно сильно над моей головой. Как бы это выглядело ... или у вас, возможно, есть ссылка на что-то с подобным решением, которое я мог бы визуально проверить? – CHM

+0

@CHM Просто добавил пример кода. – Rupert

+0

большое спасибо! Когда вы говорите: «Ограничьте ширину экземпляра Foobar, чтобы она была такой же, как высота», для этого будет работать соотношение сторон 1: 1, или я должен будет дать ему абсолютную ширину и высоту? – CHM

3

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

screenshot

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

+0

ahhh ... Я не мог заставить его работать. Я попробовал это из контейнера с этим кодом на основе того, что вы сказали: пусть радиус: CGFloat = profileImageView.bounds.size.height/2.0 profileImageView.clipsToBounds = true – CHM

+1

Вот проект xcode, показывающий, что я сделал. https://github.com/RGSSoftware/ImageViewConstraints –

+0

Randel, который полностью работает так. Моя единственная проблема заключается в том, что я запускаю эти изображения в пользовательских ячейках таблицы, которые имеют свои собственные файлы классов с элементами, установленными как IBOutlets, поэтому я не могу понять, как использовать func viewDidLayoutSubviews, потому что я вызываю их динамически в контроллер tableView с помощью cellForRowAtIndexPath и использование dequeueReusableCellWithIdentifier – CHM

0

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

  1. ваш profileImageView в раскадровке
  2. ваш profileImageView в viewDidLoad

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

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

23

Установки радиуса в viewWillLayoutSubviews позволит решить проблему

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

Это должен быть принятый ответ. Простой, практичный соответствует идеалам Apple и работает отлично. – Danny

+0

Omar Albeik Спасибо :) –

1

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

Предположим, у вас есть 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() 
}) 

Это не красиво, и может не работать для сложной многопрофильной анимации, но делает ответ на вопрос ,

-3

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

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

    @IBOutlet var widthConstraint: NSLayoutConstraint! 
    
  2. Добавить ниже код в 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 
    } 
} 
+0

это так плохо XD –

9

создать новый интерфейс в вашем файле .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" вашему ImageView. 100% работает ... Наслаждайтесь

0

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

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

override func layoutSubviews() { 
    super.layoutSubviews() 
    if self.isCircular! { 
     self.layer.cornerRadius = self.bounds.size.width * 0.50 
    } 
} 
Смежные вопросы