2016-01-17 3 views
1

Прошло некоторое время с тех пор, как я пытаюсь создать собственное представление, имеющее в правом верхнем углу простой значок.
Пользовательский вид состоит из 3 частей.Значок представления, как создать с полным подходом к автоматическому макету

  1. В красном есть пользовательский вид сами, который содержит:
  2. в синего вид контейнера
  3. в зеленой зрения значка простого UILabel

Вид контейнера и вид значка - брат.
На данный момент вид контейнера содержит UIImageView

enter image description here

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

  1. Полностью автоматическая раскладка подход
  2. Сделано программным
  3. пользовательский вид должен быть выровнен только с учетом синей рамы (вид контейнера)

Зачем? представьте, что вам нужно позиционировать этот вид, выровняв верхний край верхнего края другого вида или кнопки, было бы неплохо, если бы учитывался только контент, показанный внутри контейнера?
Здесь вы можете увидеть, как я устанавливаю ограничения. Метка помещается в верхнем правом углу контейнера.

func setUpConstraint() { 
     var horContraints = [NSLayoutConstraint]() 
     horContraints.append(NSLayoutConstraint(item: containerView, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant: 0)) 
     horContraints.append(NSLayoutConstraint(item: containerView, attribute: .Trailing, relatedBy: .Equal, toItem: badge, attribute: .CenterX, multiplier: 1, constant: 0)) 
     horContraints.append(NSLayoutConstraint(item: badge, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: 0)) 
     var verContraints = [NSLayoutConstraint]() 
     verContraints.append(NSLayoutConstraint(item: containerView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: 0)) 
     verContraints.append(NSLayoutConstraint(item: containerView, attribute: .Top, relatedBy: .Equal, toItem: badge, attribute: .CenterY, multiplier: 1, constant: 0)) 
     verContraints.append(NSLayoutConstraint(item: badge, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0)) 
     addConstraints(verContraints + horContraints)   
     containerView.addConstraint(NSLayoutConstraint(item: containerView, attribute: .Height, relatedBy: .Equal, toItem: containerView, attribute: .Width, multiplier: 1, constant: 0)) 
} 

вид Контейнер имеет также соотношение сторон ограничение, чтобы сохранить квадратный размер.
Как вы можете видеть на картинке, все кажется прекрасным, за исключением того факта, что когда я пытаюсь ограничить пользовательский вид центром его супервизора, он кажется несогласованным, потому что я хочу, чтобы представление было сосредоточено на уважении к вид контейнера (один с изображением). Значок - это своего рода украшение, такое как тень, и я не хочу, чтобы это рассматривалось.

enter image description here
Чтобы выровнять это правильно, я пытаюсь переопределить прямоугольник выравнивания путем добавления врезки, который «вырезать» половину размера этикетки.

override func alignmentRectInsets() -> UIEdgeInsets { 
     let badgeSize = badge.bounds.size 
     return UIEdgeInsets(top: badgeSize.height/2, left: 0, bottom: 0, right: badgeSize.width/2) 
    } 

Я пробовал также различные конфигурации, но я никогда не был в состоянии вписаться в нужном положении
enter image description here
Если я пытаюсь использовать другой 2 метод alignmentRectForFrame и frameForAlignmentRect (удаление alignmentRectInsets), они никогда не будут называется.
Вот что я хотел бы получить:
enter image description here
Я создал little sample code

ответ

1

Если проблема заключается в том, что вы хотите другого вида («просмотр содержимого», показывая изображение), чтобы сосредоточиться в конечном супервизии, затем просто создайте ограничения центрирования (центр x до центра x, центр y до центра y) между супервидом и представлением содержимого. Ни один закон не говорит о том, что ограничение должно быть между представлением и его прямым наблюдением; вы можете сделать ограничения между любыми парами взглядов (это одна из замечательных вещей об ограничениях).

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

enter image description here

Как вы можете видеть, Моу (средний Пеп Boy, в середине изображения) точно центрируется в виде супервизора (отображается зелеными линиями).

Для простоты в коде создан интерфейс, так что я могу показать вам все это. Вот оно:

// create the custom view 
let customView = UIView() 
customView.translatesAutoresizingMaskIntoConstraints = false 
self.view.addSubview(customView) 
customView.backgroundColor = UIColor.redColor() 
NSLayoutConstraint.activateConstraints([ 
    customView.widthAnchor.constraintEqualToConstant(100), 
    customView.heightAnchor.constraintEqualToConstant(100), 
    ]) 

// add the content view (image) to the custom view 
let contentView = UIImageView(image: UIImage(named:"pep.jpg")!) 
contentView.translatesAutoresizingMaskIntoConstraints = false 
customView.addSubview(contentView) 
NSLayoutConstraint.activateConstraints([ 
    contentView.leadingAnchor.constraintEqualToAnchor(customView.leadingAnchor), 
    contentView.bottomAnchor.constraintEqualToAnchor(customView.bottomAnchor), 
    contentView.heightAnchor.constraintEqualToAnchor(customView.heightAnchor, constant: -10), 
    contentView.widthAnchor.constraintEqualToAnchor(customView.widthAnchor, constant: -10) 
    ]) 

// add the badge (label) to the custom view 
let badge = UILabel() 
badge.translatesAutoresizingMaskIntoConstraints = false 
customView.addSubview(badge) 
badge.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.5) 
badge.font = UIFont(name: "GillSans", size: 14) 
badge.textAlignment = .Center 
badge.text = "567" 
NSLayoutConstraint.activateConstraints([ 
    badge.centerXAnchor.constraintEqualToAnchor(contentView.trailingAnchor), 
    badge.centerYAnchor.constraintEqualToAnchor(contentView.topAnchor), 
    ]) 


// position the whole thing with respect to the content view 
NSLayoutConstraint.activateConstraints([ 
    contentView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor), 
    contentView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor), 
    ]) 

Но это не полный ответ на ваш вопрос. Теперь вы должны спросить: да, но что пошло не так, когда я пытался использовать alignmentRectInsets? Ответ: вы забыли, что alignmentRectInsets влияют на выравнивание с внутренними видами, а также внешних просмотров. Другими словами, вы, конечно, можете использовать этот подход, но тогда вы должны соответствующим образом отрегулировать позицию содержимого.

Итак, вот переписывание, в котором я использую alignmentRectInsets. Во-первых, я определю пользовательский вид подкласса для нашего пользовательского представления:

class AlignedView : UIView { 
    override func alignmentRectInsets() -> UIEdgeInsets { 
     return UIEdgeInsetsMake(10, 0, 0, 10) 
    } 
} 

Теперь перепишите. Я поместил звезду (*) рядом со всеми линиями, которые изменились из предыдущего примера:

// create the custom view 
let customView = AlignedView() // * 
customView.translatesAutoresizingMaskIntoConstraints = false 
self.view.addSubview(customView) 
customView.backgroundColor = UIColor.redColor() 
NSLayoutConstraint.activateConstraints([ 
    customView.widthAnchor.constraintEqualToConstant(100), 
    customView.heightAnchor.constraintEqualToConstant(100), 
    ]) 

// add the content view (image) to the custom view 
let contentView = UIImageView(image: UIImage(named:"pep.jpg")!) 
contentView.translatesAutoresizingMaskIntoConstraints = false 
customView.addSubview(contentView) 
NSLayoutConstraint.activateConstraints([ 
    contentView.leadingAnchor.constraintEqualToAnchor(customView.leadingAnchor), 
    contentView.bottomAnchor.constraintEqualToAnchor(customView.bottomAnchor), 
    contentView.heightAnchor.constraintEqualToAnchor(customView.heightAnchor), // * 
    contentView.widthAnchor.constraintEqualToAnchor(customView.widthAnchor) // * 
    ]) 

// add the badge (label) to the custom view 
let badge = UILabel() 
badge.translatesAutoresizingMaskIntoConstraints = false 
customView.addSubview(badge) 
badge.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.5) 
badge.font = UIFont(name: "GillSans", size: 14) 
badge.textAlignment = .Center 
badge.text = "567" 
NSLayoutConstraint.activateConstraints([ 
    badge.centerXAnchor.constraintEqualToAnchor(contentView.trailingAnchor), 
    badge.centerYAnchor.constraintEqualToAnchor(contentView.topAnchor), 
    ]) 


// position the whole thing with respect to the custom view 

NSLayoutConstraint.activateConstraints([ 
    customView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor), // * 
    customView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor), // * 
    ]) 

Это дает точно такой же визуальный результат, как и раньше.

+0

Но я должен признать, что я не совсем понимаю, что вам нужно. Это может помочь, если вы нарисуете картину того, что вы, а не показываете фотографии того, что вы _getting_. – matt

+0

привет, спасибо за ваше предложение, я отредактировал вопрос. Даже если я попытаюсь инвертировать вставку, это, похоже, не сработает. Прямоугольник выравнивания все еще рассматривает метку. Фактически, похоже, что ничего не меняется, кроме кадра пользовательского представления. Я создал образец кода https://dl.dropboxusercontent.com/u/51180713/TestActivateDeactivate.zip – Andrea

+0

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

Смежные вопросы