У мене є UIView, який розміщується на екрані через кілька обмежень. Деякі обмеження належать суперпрегляду, інші належать іншим предкам (наприклад, можливо, властивість view UIViewController).
Я хочу видалити всі ці старі обмеження та помістити їх десь новим, використовуючи нові обмеження.
Як я можу це зробити, не створюючи IBOutlet для кожного окремого обмеження і не маючи пам'ятати, який вигляд має вказане обмеження?
Для деталізації, наївний підхід полягав би у створенні групи IBOutlets для кожного з обмежень, а потім включав би код виклику, такий як:
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
Проблема цього коду полягає в тому, що навіть у найпростішому випадку мені потрібно було б створити 2 IBOutlets. Для складних макетів це може легко досягти 4 або 8 необхідних IBOutlets. Крім того, мені потрібно було б переконатися, що мій заклик до зняття обмеження викликається належним чином. Наприклад, уявіть, що myViewsLeftConstraint
належить viewA
. Якби я випадково зателефонував [self.view removeConstraint:self.myViewsLeftConstraint]
, нічого б не сталося.
Примітка: Метод constraintsAffectingLayoutForAxis виглядає багатообіцяючим, але призначений лише для налагодження.
Оновлення: Багато з відповідей я отримую справу з self.constraints
, self.superview.constraints
або яким - або варіантом з них. Ці рішення не працюватимуть, оскільки ці методи повертають лише обмеження, що належать поданню, а не ті, що впливають на представлення.
Щоб пояснити проблему з цими рішеннями, розглянемо таку ієрархію поглядів:
- Дідусь
- Отче
- Я
- Синку
- Дочка
- Брате
- Я
- Дядьку
- Отче
А тепер уявіть, що ми створюємо такі обмеження і завжди прикріплюємо їх до найближчого спільного предка:
- C0: Я: така ж, як і Син (належить Мені)
- C1: Я: ширина = 100 (належить Мені)
- C2: Я: такий же зріст, як і брат (належить батькові)
- C3: Я: такий же верх, як дядько (належить Дідусю)
- C4: Я: той самий, що залишився як Дідусь (власник Діда)
- C5: Брат: такий самий, як батько (належить батькові)
- C6: Дядько: те саме, що залишилося як Дідусь (належить Дідусю)
- C7: Син: такий самий, як і дочка (належить Мені)
А тепер уявіть, що ми хочемо зняти всі обмежуючі фактори Me
. Будь-яке правильне рішення слід видалити [C0,C1,C2,C3,C4]
і більше нічого.
Якщо я використовую self.constraints
(де self - це Я), я отримаю [C0,C1,C7]
, оскільки це єдині обмеження, якими володію Я. Очевидно, що цього буде недостатньо, щоб видалити це, оскільки воно відсутнє [C2,C3,C4]
. Крім того, воно видаляється C7
без потреби.
Якщо я використаю self.superview.constraints
(де Я - це Я), я отримаю [C2,C5]
, оскільки це обмеження, якими володіє Батько. Очевидно, що ми не можемо видалити все це, оскільки C5
це абсолютно не пов'язано з Me
.
Якщо я використовую grandfather.constraints
, я отримаю [C3,C4,C6]
. Знову ж таки, ми не можемо вилучити їх усіх, оскільки вони C6
повинні залишатися цілими.
Підхід грубої сили полягає в тому, щоб прокрутити кожного з предків виду (включаючи самого себе), і перевірити, firstItem
чи secondItem
є сам погляд; якщо так, зніміть це обмеження. Це призведе до правильного рішення, повернення [C0,C1,C2,C3,C4]
та лише цих обмежень.
Однак я сподіваюся, що є більш елегантне рішення, ніж необхідність перебирати весь список предків.