Bir görünüm gizlendiğinde diğer görünümleri taşımak için otomatik düzen nasıl kullanılır?


333

Özel Hücremi IB'de tasarladım, sınıflandırdım ve çıkışlarımı özel sınıfıma bağladım. Hücre içeriğinde üç alt görünümü var: UIView (cdView) ve iki etiket (titleLabel ve emailLabel). Her satır için mevcut verilere bağlı olarak, bazen UIView ve hücremde iki etiket ve bazen sadece iki etiket görüntülenmesini istiyorum. Ne yapmaya çalışıyorum UIView özelliği gizli olarak ayarladıysanız veya iki etiket sola hareket edecek denetiminden kaldıracak şekilde kısıtlamaları ayarlamaktır. 10px için UIView öncü kısıtlamasını (Hücre içeriği) ve sonraki görünüme (UIView) 10 piksel için UILabels önde gelen Kısıtlamaları ayarlamaya çalıştım. Daha sonra kodumda

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];

if ([record.imageURL is equalToString:@""]) {
     cell.cdView.hidden = YES;
}

Cell.cdView gizleme ve etiketleri sola taşımak istiyorum ancak hücre aynı konumda kalıyor. Cell.cdView denetiminden kaldırmaya çalıştım ama o da işe yaramadı. Ne hakkında olduğumu netleştirmek için resim ekledim.

hücre

Bunu programlı olarak nasıl yapacağımı biliyorum ve bu çözümü aramıyorum. İstediğim, IB'de kısıtlamalar ayarlamak ve diğer görünümler kaldırılırsa veya gizlenirse alt görünümlerimin dinamik olarak hareket etmesini beklerim. Bunu IB'de otomatik yerleşim ile yapmak mümkün müdür?

.....

Kısıtlama değeri çalışma zamanını değiştirin - bu yanıtı
Kampai

Bu özel durum için bir UIStackView de kullanabilirsiniz. cd'yi gizlediğinizde, etiketler alanlarını kaplayacak
Marco Pappalardo

Yanıtlar:


373

Mümkün, ama biraz ekstra iş yapmanız gerekecek. İlk olarak yoldan çıkmak için birkaç kavramsal şey var:

  • Gizli görünümler, çizmemelerine rağmen , Otomatik Düzen'e hala katılır ve genellikle çerçevelerini korur ve diğer ilgili görünümleri yerlerinde bırakır.
  • Bir görünümü denetiminden kaldırırken, ilgili tüm kısıtlamalar da bu görünüm hiyerarşisinden kaldırılır.

Sizin durumunuzda, bu muhtemelen şu anlama gelir:

  • Sol görünümünüzü gizlenecek şekilde ayarlarsanız, sol görünüm hala yer kapladığından (görünür olmasa da) etiketler yerinde kalır.
  • Sol görünümünüzü kaldırırsanız, etiketlerinizin sol kenarları için artık kısıtlama olmadığından etiketleriniz büyük olasılıkla belirsiz bir şekilde kısıtlanacaktır.

Yapmanız gereken , etiketlerinizi akıllıca aşırı kısıtlamaktır . Mevcut kısıtlamalarınızı (diğer görünüme 10pts boşluk) yalnız bırakın, ancak başka bir kısıtlama ekleyin: etiketlerinizin sol kenarlarını, denetimin sol kenarından gerekli olmayan bir önceliğe 10pts uzaklaştırın (varsayılan yüksek öncelik muhtemelen iyi çalışır).

Ardından, sola hareket etmelerini istediğinizde, sol görünümü tamamen kaldırın. Sol görünümdeki zorunlu 10pt kısıtlaması, ilgili görünümle birlikte kaybolacak ve etiketlerin denetiminden 10 puan uzakta olması için yalnızca yüksek öncelikli bir kısıtlama bırakacaksınız. Bir sonraki düzen geçişinde bu, denetimin genişliğini doldurana kadar kenarların etrafındaki boşluklarınız için sola genişlemesine neden olmalıdır.

Önemli bir uyarı: Soldaki görüntünüzü resimde geri almak isterseniz, yalnızca görünüm hiyerarşisine geri eklemekle kalmaz , aynı zamanda tüm kısıtlamalarını da yeniden oluşturmanız gerekir . Bu, görünüm tekrar gösterildiğinde, görünüm ve etiketleri arasındaki 10pt boşluk sınırını geri koymanın bir yoluna ihtiyacınız olduğu anlamına gelir.


8
Bu cevap kesinlikle işe yarayacak olsa da, IMO, çeşitli kullanım durumlarını işlemek için aşırı kısıtlama bir kod kokusu gibi görünüyor - özellikle görünümü tekrar göstermek istediğiniz kaldırılmış görünümler için tüm kısıtlamaları yeniden oluşturmanız gerektiğinden.
memmons

Bence, bu yol değil. Bunun yerine gizlemek istediğiniz görünüm için bir genişlik / yükseklik kısıtlaması kullanmalısınız.
ullstrm

26
Saygılarımla katılmıyorum. (Örneğin) görünümün genişliğini 0 olarak ayarlarsanız, iki sorunla karşılaşırsınız. Birincisi, şimdi denetim ve görünür görünüm arasında çift boşluk var: |-(space)-[hidden(0)]-(space)-[visible]etkili |-(2*space)-[visible]. İkincisi, bu görünüm kendi görünüm alt ağacına ve kısıtlamalarına bağlı olarak kısıtlama ihlalleri atmaya başlayabilir - bir görünümü 0 genişlikte keyfi olarak sınırlayabileceğinizi ve çalışmaya devam edebileceğini garanti edemezsiniz.
Tim

1
İçsel içerik boyutuna sahip bir görünüm kullanıyorsanız Tim'in cevabı benzersiz bir yol gibi görünüyor.
balkoth

Teşekkürler Tim. Kısıtlama uyumsuzluklarından kaçınmak için daha yüksek önceliğe sahip bir kısıtlama ayarladım, ancak şimdi çift boşlukla ilgili bir sorun olduğunu anlıyorum. Bu problemi yaşamadım çünkü iki görüşü asla birlikte göstermem (benim durumum:) |-[otherViews]-[eitherThis][orThis]-|, ama sonunda bu problemle karşılaşırdım.
Ferran Maylinch

207

Çalışma zamanı sırasında kısıtlama eklemek veya kaldırmak, performansı etkileyebilecek ağır bir işlemdir. Ancak, daha basit bir alternatif var.

Gizlemek istediğiniz görünüm için bir genişlik kısıtlaması ayarlayın. Diğer görünümleri, bu görünüme giden yatay bir boşlukla sınırlayın.

Gizlemek .constantiçin genişlik sınırlamasını 0.f olarak güncelleyin. Diğer görünümler pozisyon almak için otomatik olarak sola hareket edecektir.

Daha fazla ayrıntı için diğer cevabımı burada görebilirsiniz:

Çalışma zamanında etiket kısıtlamaları nasıl değiştirilir?


29
Bu çözümle ilgili tek sorun, sol kenar boşluğunun muhtemelen istediğiniz şeyin iki katı olacağıdır, bu yüzden bu kısıtlamalardan birini de güncelleyeceğim, ancak o zaman bile bunun alt görünümü kaldırmadan daha az iş olduğunu düşünüyorum.
José Manuel Sánchez

2
@ skinsfan00atg İçsel içerik boyutuna sahip bir görünüm kullanıyorsanız bu çözümü kullanamazsınız.
balkoth

@balkoth neden olmasın? Sadece içerik sarılma önceliğini azaltabilirsiniz
Max MacLeod

2
@MaxMacLeod İçerik sarılma önceliğini azaltırsanız, gerçek içerik boyutunu kullanmazsanız, kısıtlamayla belirtilen boyutu kullanırsınız.
balkoth

2
@MaxMacLeod Tamam, ne demek istediğini anladım. Görünümü gizlemek istediğinizde ve tekrar göstermek istediğinizde kodda sıkıştırma direnci önceliğini 0 (içerik sarılma değil) olarak ayarlamanız gerekir. Bunun dışında, görünümün boyutunu 0 olarak ayarlamak için arayüz oluşturucuya bir kısıtlama eklemeniz gerekir. Kodda bu karşıtlığa dokunmanıza gerek yoktur.
balkoth

87

Yalnızca iOS 8+ ' yi destekleyen kullanıcılar için yeni bir boole özelliği etkin . Yalnızca gerekli kısıtlamaların dinamik olarak etkinleştirilmesine yardımcı olacaktır

PS Kısıtlama çıkışı güçlü değil, zayıf olmalıdır

Örnek:

@IBOutlet weak var optionalView: UIView!
@IBOutlet var viewIsVisibleConstraint: NSLayoutConstraint!
@IBOutlet var viewIsHiddenConstraint: NSLayoutConstraint!

func showView() {
    optionalView.isHidden = false
    viewIsVisibleConstraint.isActive = true
    viewIsHiddenConstraint.isActive = false
}

func hideView() {
    optionalView.isHidden = true
    viewIsVisibleConstraint.isActive = false
    viewIsHiddenConstraint.isActive = true
}

Ayrıca film şeridindeki bir hatayı düzeltmek Installediçin bu kısıtlamalardan birinin onay kutusunun işaretini kaldırmanız gerekir .

UIStackView (iOS 9+)
Bir başka seçenek de görünümlerinizi sarmaktırUIStackView . Görünüm gizlendikten sonra UIStackViewdüzeni otomatik olarak güncelleyecek


aktif kısmen çalışır. Ancak, yeniden kullanılabilir bir hücre içinde kullanırsam, etkinleştirmeden devre dışı bırakmaya çalışır, çalışır, ancak devre dışı bırakmak için etkinleştirmez. Herhangi bir fikir? Ya da belki bir örnek verebilir misiniz?
Aoke Li

10
Devre dışı bırakılan kısıtlama yüklenmediği veya yeniden konumlandırılmadığı için olur. Kısıtlama çıktınız güçlü değil, zayıf değil
Silmaril

Bu "aktif" mülkü nerede bulabiliriz?
Lakshmi Reddy


Aşırı kısıtlama + ayarlanmış kısıtlama aktivitesi en makul cevap olabilir gibi görünüyor.
Ting Yi Shih

68

UIStackViewhiddenözellik alt görünümlerinden herhangi birinde (iOS 9+) değiştirildiğinde görünümlerini otomatik olarak yeniden konumlandırır .

UIView.animateWithDuration(1.0) { () -> Void in
   self.mySubview.hidden = !self.mySubview.hidden
}

Bir demo için bu WWDC videosunda 11 :48'e atlayın :

Otomatik Mizanpaj Gizemleri, Bölüm 1


Yuvalanmış bir yığın görünümü sakladım ve tüm yığın görünümü kayboldu.
Ian Warburton

5
Bu kabul edilen cevap olmalı. Arayüz oluşturucu tasarımı ile ilgili wwdc 2015'in elma önerilerini takiben.
thibaut noah

@thibautnoah Peki iOS 8- desteği ne olacak?
bagage

5
@bagage Eğer facebook veya google değilseniz, bırakabilirsiniz. İOS 9 ile kapsama alanı sayesinde, cihazların% 90'ından fazlasını, fazlasıyla destekleyeceksiniz. Aşağıdaki destek geliştirme sürecinize
zarar

16

@IBDesignableProjem özel bir alt sınıf UILabel(renk, yazı tipi, iç metin vb. Tutarlılık sağlamak için) kullanır ve ben aşağıdaki gibi bir şey uyguladık:

override func intrinsicContentSize() -> CGSize {
    if hidden {
        return CGSizeZero
    } else {
        return super.intrinsicContentSize()
    }
}

Bu, etiket alt sınıfının Otomatik Mizanpaj'da yer almasına izin verir, ancak gizlendiğinde yer kaplamaz.


13

Google çalışanları için: Max'in cevabına dayanarak, birçoğunun fark ettiği dolgu sorununu çözmek için etiketin yüksekliğini arttırdım ve bu yüksekliği gerçek dolgu yerine ayırıcı olarak kullandım. Bu fikir, görünüm içeren herhangi bir senaryo için genişletilebilir.

İşte basit bir örnek:

IB Ekran Görüntüsü

Bu durumda, Yazar etiketinin yüksekliğini uygun bir değerle eşleştiriyorum IBOutlet:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

ve kısıtlamanın yüksekliğini ayarladığımda, 0.0f"doldurmayı" koruyoruz, çünkü Oynat düğmesinin yüksekliği buna izin veriyor.


Yeni olanlar için NSLayoutConstraintben güncellemek istediğiniz inanıyoruz constantözelliği , aramalarınızdan authorLabelHeight.
Kyle

8

uiview ve etiketler arasındaki kısıtlamayı IBOutlet olarak bağlayın ve gizli ayarlandığında öncelik üyesini daha düşük bir değere ayarlayın = EVET


3
Bir kez kurulduktan sonra bir NSLayoutConstraint'in önceliğini ayarlayamazsınız; farklı bir önceliğe sahip yeni bir kısıtlamayı kaldırmanız ve okumalısınız.
Tim

7
Bu yöntemi çalışmak için aldım. Düğmeyi gizlemek ve etiketi genişletmek için gereken bir etiket ve bir düğme kullanan bir durum var. Biri öncelik 751, diğeri 750 ile olmak üzere iki kısıtlamam var. Sonra düğmeyi gizlediğimde öncelikleri değiştiriyorum ve etiketin uzunluğu artıyor. Unutulmamalıdır ki, daha yüksek önceliği 1000 yapmaya çalışırsanız, "Önceden gerekli olandan kurulu bir kısıtlamaya (veya tersine) dönüştürülmesinin desteklenmediği" hatası alıyorsunuz. Öyleyse yapma ve iyi görünüyorsun. Xcode 5.1 / viewDidLoad.
John Bushnell

8

Yaptığım şey 2 xib oluşturmaktı. Biri soldan görünüm ve diğeri onsuz. Her iki denetleyiciye de kaydoldum ve sonra cellForRowAtIndexPath sırasında hangisinin kullanılacağına karar verdim.

Aynı UITableViewCell sınıfını kullanırlar. Dezavantajı, xib'ler arasında içeriğin bir miktar çoğaltılmasıdır, ancak bu hücreler oldukça basittir. Ters tarafı, görünümü kaldırma, güncelleme kısıtlamaları, vb manuel olarak yönetmek için bir grup kod yok olmasıdır.

Genel olarak, teknik olarak farklı düzenler olduğundan ve bu nedenle farklı xib'lere sahip olmaları gerektiğinden, bu muhtemelen daha iyi bir çözümdür.

[self.table registerNib:[UINib nibWithNibName:@"TrackCell" bundle:nil] forCellReuseIdentifier:@"TrackCell"];
[self.table registerNib:[UINib nibWithNibName:@"TrackCellNoImage" bundle:nil] forCellReuseIdentifier:@"TrackCellNoImage"];

TrackCell *cell = [tableView dequeueReusableCellWithIdentifier:(appDelegate.showImages ? @"TrackCell" : @"TrackCellNoImage") forIndexPath:indexPath];

7

Bu durumda, Yazar etiketinin yüksekliğini uygun bir IBOutlet ile eşleştiriyorum:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

ve kısıtlamanın yüksekliğini 0.0f olarak ayarladığımda, "doldurmayı" koruyoruz, çünkü Oynat düğmesinin yüksekliği buna izin veriyor.

cell.authorLabelHeight.constant = 0;

resim açıklamasını buraya girin resim açıklamasını buraya girin


6

İki UIStackView Yatay ve Dikey kullanın, yığındaki bazı alt görünümler gizlendiğinde diğer yığın alt görünümleri taşınır, Dağıtım -> İki UILabel içeren Dikey yığın için Orantısal Olarak Doldur'u kullanın ve ilk UIView için genişlik ve yükseklik korumaları ayarlamanız gerekirresim açıklamasını buraya girin


2

Bunu deneyin, aşağıdaki kodu uyguladım,

Diğer üç görünüm eklendi görünümünde ViewController bir Görünüm var , herhangi bir görünüm gizlendiğinde diğer iki görünüm hareket edecek, Aşağıdaki adımları izleyin. ,

1.ViewController.h Dosyası

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewOne;
@property (strong, nonatomic) IBOutlet UIView *viewTwo;
@property (strong, nonatomic) IBOutlet UIView *viewThree;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewOneWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewTwoWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewThreeWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewBottomWidth;
@end

2.ViewController.m

 #import "ViewController.h"
 @interface ViewController ()
{
  CGFloat viewOneWidthConstant;
  CGFloat viewTwoWidthConstant;
  CGFloat viewThreeWidthConstant;
  CGFloat viewBottomWidthConstant;
}
@end

@implementation ViewController
@synthesize viewOne, viewTwo, viewThree;

- (void)viewDidLoad {
  [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a 
  nib.

  /*
   0  0   0
   0  0   1
   0  1   0
   0  1   1
   1  0   0
   1  0   1
   1  1   0
   1  1   1
   */

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:YES];


  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

 //    [viewOne setHidden:YES];
 //    [viewTwo setHidden:YES];
 //    [viewThree setHidden:NO];

//    [viewOne setHidden:YES];
//    [viewTwo setHidden:YES];
//    [viewThree setHidden:YES];

 [self hideShowBottomBar];
  }

- (void)hideShowBottomBar
{
  BOOL isOne = !viewOne.isHidden;
  BOOL isTwo = !viewTwo.isHidden;
  BOOL isThree = !viewThree.isHidden;

  viewOneWidthConstant = _viewOneWidth.constant;
  viewTwoWidthConstant = _viewTwoWidth.constant;
  viewThreeWidthConstant = _viewThreeWidth.constant;
  viewBottomWidthConstant = _viewBottomWidth.constant;

   if (isOne && isTwo && isThree) {
    // 0    0   0
    _viewOneWidth.constant = viewBottomWidthConstant / 3;
    _viewTwoWidth.constant = viewBottomWidthConstant / 3;
    _viewThreeWidth.constant = viewBottomWidthConstant / 3;
    }
    else if (isOne && isTwo && !isThree) {
     // 0    0   1
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = 0;
    }
   else if (isOne && !isTwo && isThree) {
    // 0    1   0
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
    }
    else if (isOne && !isTwo && !isThree) {
    // 0    1   1
    _viewOneWidth.constant = viewBottomWidthConstant;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && isTwo && isThree) {
    // 1    0   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
   }
   else if (!isOne && isTwo && !isThree) {
    // 1    0   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && !isTwo && isThree) {
    // 1    1   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant;
   }
   else if (isOne && isTwo && isThree) {
    // 1    1   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
  }

 - (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
 }
 @end

resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin

Umarım bu mantık bir tanesine yardım eder.


1

Benim durumumda ben sabiti set yüksekliği kısıtlaması için 0.0fve ayrıca set hiddeniçin özellik YES.

Görünümü (alt görünümlerle birlikte) tekrar göstermek için tam tersini yaptım: Yükseklik sabitini sıfır olmayan bir değere ayarladım ve hiddenözelliği olarak ayarladım NO.


1

Yatay yığın görünümü kullanacağım. Alt görünüm gizlendiğinde çerçeveyi kaldırabilir.

Aşağıdaki görüntüde, kırmızı görünüm içeriğiniz için gerçek kapsayıcıdır ve turuncu denetime (ShowHideView) kadar 10pt izleme alanı vardır, daha sonra ShowHideView'ı IBOutlet'e bağlayın ve programlı olarak gösterin / gizleyin / kaldırın.

  1. Bu görünüm görünür olduğunda / kurulur.

görünüm görülebilir

  1. Bu görünüm gizlendiğinde / kurulmadığında gerçekleşir.

görünüm gizli / kaldırıldı


1

Bu, öncelik kısıtlamasını kullanan başka bir çözümüm. Fikir, genişliği 0 olarak ayarlar.

  1. kap görünümü oluşturma (turuncu) ve genişliği ayarlama. resim açıklamasını buraya girin

  2. içerik görünümü oluşturma (kırmızı) ve izleyen alanı 10pt denetleyecek şekilde ayarlama (turuncu). Sondaki boşluk kısıtlamalarına dikkat edin, farklı önceliğe sahip 2 arka sınırlama vardır. Düşük (= 10) ve Yüksek (<= 10). Belirsizliği önlemek için bu önemlidir. resim açıklamasını buraya girin

  3. Görünümü gizlemek için turuncu görünümün genişliğini 0 olarak ayarlayın. resim açıklamasını buraya girin


0

No_scene'nin önerdiği gibi, bunu çalışma zamanında kısıtlamanın önceliğini değiştirerek kesinlikle yapabilirsiniz. Bu benim için çok daha kolaydı çünkü kaldırılması gereken birden fazla engelleme görünümü vardı.

ReactiveCocoa kullanan bir pasaj:

RACSignal* isViewOneHiddenSignal = RACObserve(self.viewModel, isViewOneHidden);
RACSignal* isViewTwoHiddenSignal = RACObserve(self.viewModel, isViewTwoHidden);
RACSignal* isViewThreeHiddenSignal = RACObserve(self.viewModel, isViewThreeHidden);
RAC(self.viewOne, hidden) = isViewOneHiddenSignal;
RAC(self.viewTwo, hidden) = isViewTwoHiddenSignal;
RAC(self.viewThree, hidden) = isViewThreeHiddenSignal;

RAC(self.viewFourBottomConstraint, priority) = [[[[RACSignal
    combineLatest:@[isViewOneHiddenSignal,
                    isViewTwoHiddenSignal,
                    isViewThreeHiddenSignal]]
    and]
    distinctUntilChanged]
    map:^id(NSNumber* allAreHidden) {
        return [allAreHidden boolValue] ? @(780) : @(UILayoutPriorityDefaultHigh);
    }];

RACSignal* updateFramesSignal = [RACObserve(self.viewFourBottomConstraint, priority) distinctUntilChanged];
[updateFramesSignal
    subscribeNext:^(id x) {
        @strongify(self);
        [self.view setNeedsUpdateConstraints];
        [UIView animateWithDuration:0.3 animations:^{
            [self.view layoutIfNeeded];
        }];
    }];


0

Çözümünüzü almak için uiviews'imi nasıl yeniden hizalayacağım:

  1. Bir UIImageView öğesini sürükleyin ve sola yerleştirin.
  2. Bir UIView öğesini sürükleyin ve UIImageView öğesinin sağına yerleştirin.
  3. Baştaki ve sondaki kısıtlamaları sıfır olan UIView'in içine iki UILabel sürükleyin.
  4. UIImagView yerine denetlemek için 2 etiket içeren UIView'in ön sınırını ayarlayın.
  5. UIImageView gizlenmişse, denetlemek için önde gelen kısıtlama sabitini 10 piksel olarak ayarlayın. ELSE, önde gelen kısıtlama sabitini 10 px + UIImageView.width + 10 px olarak ayarlayın.

Kendi kurallarýmý yarattým. Kısıtlamaları etkilenebilecek herhangi bir uiview'i gizlemek / göstermek istediğinizde, bir uiview içindeki tüm etkilenen / bağımlı alt görünümleri ekleyin ve önde gelen / sondaki / üst / alt kısıtlama sabitini programlı olarak güncelleyin.


0

Bu eski bir soru ama yine de yardımcı olacağını umuyorum. Android'den gelen bu platformda isVisible, görünümünden gizlemek için kullanışlı bir yönteminiz var, ancak otomatik görünüm görünümü çizdiğinde çerçevenin dikkate alınmadığı da var.

uzantı ve "genişletmek" uiview kullanarak hızlı bir şekilde burada bir uygulama ios (neden zaten UIKit içinde olduğundan emin değilim) yapabilirsiniz 3:

    func isVisible(_ isVisible: Bool) {
        self.isHidden = !isVisible
        self.translatesAutoresizingMaskIntoConstraints = isVisible
        if isVisible { //if visible we remove the hight constraint 
            if let constraint = (self.constraints.filter{$0.firstAttribute == .height}.first){
                self.removeConstraint(constraint)
            }
        } else { //if not visible we add a constraint to force the view to have a hight set to 0
            let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0)
            self.addConstraint(height)
        }
        self.layoutIfNeeded()
    }

0

bunu yapmanın uygun yolu, kısıtlamaları isActive = false ile devre dışı bırakmaktır. ancak bir kısıtlamanın devre dışı bırakılmasının onu kaldırdığını ve serbest bıraktığını unutmayın, böylece onlar için güçlü çıkışlara sahip olmanız gerekir.


0

En kolay çözüm UIStackView (yatay) kullanmaktır. Yığın görünümüne ekle: ilk görünüm ve etiketli ikinci görünüm. Ardından, ilk görünümün isHidden özelliğini false olarak ayarlayın. Tüm kısıtlamalar hesaplanacak ve otomatik olarak güncellenecektir.


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.