Çalışma zamanında belirli bir alt görünüm için otomatik düzeni devre dışı bırakabilir miyim?


104

Çerçevesinin programlı olarak işlenmesi gereken bir görünümüm var - bu, çerçevenin başlangıcını değiştirerek bir süpervizörün etrafında kaydırılan ve yakınlaştırılan içeriğine saran bir tür belge görünümü. Otomatik düzen, çalışma zamanında bununla savaşır.

Otomatik düzeni devre dışı bırakmak, diğer görünümlerin düzenini işlemek için makul bir şekilde kullanılabileceği için biraz zor görünüyor. Görünüşe göre isteyebileceğim şey bir tür "boş kısıtlama".

Yanıtlar:


168

Ben de aynı sorunu yaşadım. Ama ben çözdüm.
Evet, UIViewXcode 4.3 ve sonrasında varsayılan olarak ayarlanan tüm xib veya film şeridi için devre dışı bırakmak yerine, belirli bir çalışma zamanında otomatik düzeni devre dışı bırakabilirsiniz .

Set translatesAutoresizingMaskIntoConstraintsiçin YESsize subview çerçevesini belirlemeden önce,:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
Bu, çok sayıda görüşe sahip bazı daha karmaşık durumlar için aşırı gibi görünüyor. Bu kadar basit bir şey için sorun değil.
esh

@MuhammadAamirALi alt görünümü kaldırıp tekrar eklemek performansın düşmesi olabilir.Daha iyi bir çözüm arşivleyebilir miyiz?
Nhat Dinh

2
@DinhNhat cevabı açıkladım. Alt görünümü kaldırıp yeniden eklemek gerekli değildir.
Leandros

5
Bana uyarıyı gösteriyor: "Aynı anda kısıtlamaları karşılayamıyor."
NSPratik

1
Günümü
Tintenklecks

50

Otomatik Düzen'in çalışma zamanında bazı çerçeve ayarlarımı geçersiz kıldığı benzer bir sorunla karşılaştım (bazı durumlarda yeni bir görünüm denetleyicisine iten dinamik bir görünüme sahiptim ... itip ardından Geri'ye basmak ilk görünümü sıfırlar).

Düzenleme kodumu viewDidLayoutSubviewsView Controller'ıma ekleyerek bunu aştım. Bu, mojo'nun çağrıldığı kısıtlamadan sonra çağrılıyor gibi görünüyor, ancak viewDidAppear'dan önce çağrılıyor, bu nedenle kullanıcı daha akıllı değil.


1
Self.navigationItem.titleView için çalışmaz. Hala çerçeve değişikliğine saygı duymuyor.
Henrik Erlandsson

1
Bir başlık görünümünün çerçevesiyle karıştırmaya çalışıyorsanız, onu bir konteyner görünümünün içine koyar ve konteyner görünümünü, navigationItem'in özel bir görünümü olarak eklerim.
jmstone617

2
Bu benim için de çalıştı. Bu geçici çözümü keşfetmeden önce kafamı meşhur duvara vurarak 2h: 22m harcadım.
TMc

Teşekkürler dostum. İkinci günümde bu sorunla mücadele ediyorum ve şimdi işe yarıyor!
apostolov

28

Belki sadece ayar translatesAutoresizingMaskIntoConstraintsiçin YES(ve bu görüşü etkileyen ek sınırlamalar ekleyerek değil) otomatik düzen sistemini savaşmadan çerçeveyi ayarlamak izin verir.


17

İOS 8'de bir NSLayoutConstraint'i aktif olacak veya olmayacak şekilde ayarlayabilirsiniz. Dolayısıyla, arayüz oluşturucuyu kullanıyorsam, tüm kısıtlamalarımı bir OutletCollection'a eklerim ve ardından şunu kullanarak etkinleştirir veya devre dışı bırakırım:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

Burada kullandığım belirli uygulama, dikey ve yatay modda farklı kısıtlamalara sahip ve cihazın dönüşüne göre etkinleştiriyorum / devre dışı bırakıyorum. Bu, her iki yön için arayüz oluşturucuda bazı karmaşık düzen değişiklikleri oluşturabileceğim ve yine de ayrıntılı otomatik düzen kodu olmadan otomatik düzeni kullanabileceğim anlamına geliyor.

Ya da removeConstraints ve addConstraints kullanarak etkinleştirebilir / devre dışı bırakabilirsiniz.


Bu kadar eski bir soruyu ele geçirdiğim için özür dilerim, ancak ilk etapta farklı düzenler için düzen kısıtlamaları eklemeyi nasıl başardığınızı sorabilir miyim? Arayüz oluşturucunun içinde kısıtlamaları etkinleştirmek / devre dışı bırakmak için bir seçenek bulamıyorum. Ya da sadece her iki düzen için kısıtlamalar eklediniz ve arayüz oluşturucuyu geçersiz (geçersiz kılma) kısıtlamalardan şikayet eden görmezden mi geldiniz?
Malte

Bunu boyut sınıfları kullanarak yapabilirsiniz: developer.apple.com/library/ios/recipes/… , ancak bunu bu şekilde yapamadım çünkü ben de iOS 7'yi destekliyordum ve boyut sınıfları iOS 7'yi tam olarak desteklemiyor Çakışan kısıtlamanın önceliğini düşürerek yaptım. İdeal değil ama uyarıyı engelliyor. Sanırım ben de böyle yaptım ....
bandejapaisa

9

Bunun başka birine yardımcı olup olmayacağını bilmiyorum ama bunu kolaylaştırmak için bir kategori yazdım çünkü kendimi bunu çok yaparken buluyorum.

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

Bunu şu şekilde kullanıyorum:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

Umarım yardımcı olur.


Parlak ! Herhangi bir UIView için basit bir "hideControl" işlevi yazmak için kodunuzun değiştirilmiş bir sürümünü kullandım. Temelde bir UIView yüksekliğini 0 olarak ayarlar, ancak en önemlisi, Otomatik Yerleşimin onu düzgün bir şekilde işlemesi için kodunuzu kullanır ("someView.hidden = DOĞRU" kullanmanın aksine). Bu nedenle, gizli kontrolün altında görünen ve ona bağlı dikey boşlukları olan kontroller, daha önce gizli görünümün göründüğü boşluğu doldurmak için ekranda yukarı kayacaktı.
Mike Gledhill

6

Ayarlayabilirsiniz translatesAutoresizingMaskIntoConstraintstürünü Booleansize xib / film şeridindeki istediğiniz UIView Nitelikler Runtime Tanımlı Kullanıcı, değer Evet.


2
  • 4.5'te proje aç
  • Film şeridi seçin
  • Dosya denetçisini açın
  • Arayüz Oluşturucu Belgesi altında 'Otomatik Düzen Kullan' seçeneğinin işaretini kaldırın

Bazı görünümler için otomatik düzen kullanmak istiyorsanız, birden fazla film şeridine bölünebilirsiniz.


10
Bu, tüm film şeridi / uç için otomatik düzeni devre dışı bırakır. Aradığım şey, bir film şeridi / uç içinde belirli alt görüntülere sahip olmanın bir yoluydu (ideal olarak programlı), geri kalanını film şeridi / uç ne olursa olsun yapmadan bırakırken otomatik düzen kullanmıyor.
terriblememory

Birden çok storyboard kullanabilir ve gerektiğinde otomatik düzen içeren / içermeyenleri çağırabilirsiniz: // UIStoryboard * sb = [UIStoryboard storyboardWithName: @ "Storyboard" paketi: [NSBundle mainBundle]]; DetailViewController * dvController = [sb instantiateViewControllerWithIdentifier: entry.viewName];
Mike Bobbitt

1

Benim için alt görünümü programlı olarak oluşturmak için çalıştı, benim durumumda otomatik düzen merkezi etrafında döndürmem gereken bir görünümle uğraşıyordu, ancak bu görünümü programlı olarak oluşturduğumda işe yaradı.


1

Benim görüşüme göre bir Etiket ve Metin vardı. Etiket pan hareketi yaptı. Etiket, sürükleme sırasında iyi hareket eder. Ancak metin kutusu klavyesini kullandığımda, etiket konumunu otomatik düzende tanımlanan orijinal konuma sıfırlıyor. Aşağıdakileri etiket için hızlı bir şekilde eklediğimde sorun çözüldü. Bunu viewWillAppear'a ekledim ancak hedef alana erişiminizin olduğu hemen hemen her yere eklenebilir.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

Bu bana hikaye tahtaları veya xib dosyaları olmayan bir projede oldu. Hepsi% 100 kod. Altta bir reklam şeridi vardı ve görünüm sınırlarının reklam şeridinde durmasını istedim. Görünüm, yüklendikten sonra otomatik olarak yeniden boyutlandırılır. Bu sayfadaki her çözümü denedim ama hiçbiri işe yaramadı.

Kısaltılmış yüksekliğe sahip bir alt görünüm oluşturdum ve bunu kontrolörün ana görünümüne yerleştirdim. Sonra tüm içeriğim alt görünüme girdi. Bu, tahılın tersine gidiyormuş gibi hissettiren hiçbir şey yapmadan sorunu çok kolay çözdü.

Pencereyi dolduran normal boyutta olmayan bir görünüm istiyorsanız, bunun için bir alt görünüm kullanmanız gerektiğini düşünüyorum.


0

Otomatik düzen ile başlatılan bir projeye katıldığım benzer bir senaryoyla karşılaştım, ancak birkaç görünümde dinamik ayarlamalar yapmam gerekiyordu. İşte benim için ne işe yaradı:

  1. Arayüz oluşturucudaki görünümler veya bileşenler YOKTUR.

  2. Tahsis / init ile başlayarak ve çerçevelerini uygun şekilde ayarlayarak tamamen programlı olarak görünümlerinizi ekleyin.

  3. Bitti.


0

Otomatik düzeni devre dışı bırakmak yerine, yeni kısıtlamayı değiştirdiğiniz çerçeve ile hesaplarım. Bu bana uygun bir yol gibi görünüyor. Kısıtlamalara dayanan bileşenleri ayarlıyorsanız, bunları uygun şekilde ayarlayın.

Örneğin, iki görünüm (myView ve otherView) arasında 0'lık bir dikey sınırlamanız varsa ve bir kaydırma hareketiniz veya myView'ın yüksekliğini ayarlayan bir şeyiniz varsa, kısıtlamayı ayarlanan değerlerle yeniden hesaplayabilirsiniz.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

Otomatik düzen kullananlarınız için lütfen çözümüme buradan göz atın . @IBOutletAyarlamak istediğiniz kısıtlamalardan yapmalı ve sonra bunların sabitlerini değiştirmelisiniz.


-16

xib dosyasıysa:

  1. .xib dosyasını seçin
  2. "Dosyanın Sahibi" ni seçin
  3. Yardımcı Programları göster
  4. tıklayın: "Dosya Denetçisi"
  5. "Arayüz Oluşturucu Belgesi" altında şu devre dışı bırakın: "Otomatik Düzen Kullan"

1
Hayır, bu tüm xib için otomatik düzeni devre dışı bırakır. Aradığım şey, otomatik düzen sisteminden yalnızca belirli bir alt görünümü çıkarmanın bir yolu.
terriblememory
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.