Làm cách nào để sử dụng bố cục tự động để di chuyển các chế độ xem khác khi chế độ xem bị ẩn?


332

Tôi đã thiết kế Cell tùy chỉnh của mình trong IB, phân lớp nó và kết nối các cửa hàng của tôi với lớp tùy chỉnh của tôi. Tôi có ba mục phỏng vấn trong nội dung ô đó là: UIView (cdView) và hai nhãn (titleLabel và emailLabel). Tùy thuộc vào dữ liệu có sẵn cho mỗi hàng, đôi khi tôi muốn có UIView và hai nhãn được hiển thị trong ô của tôi và đôi khi chỉ có hai nhãn. Những gì tôi đang cố gắng làm là đặt các ràng buộc theo cách đó nếu tôi đặt thuộc tính UIView thành ẩn hoặc tôi sẽ xóa nó khỏi giám sát, hai nhãn sẽ di chuyển sang bên trái. Tôi đã cố gắng đặt ràng buộc hàng đầu của UIView thành Superview (Nội dung ô) cho 10px và các ràng buộc hàng đầu của UILabels cho 10 px cho chế độ xem tiếp theo (UIView). Sau đó trong mã của tôi

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

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

Tôi đang ẩn cell.cdView của mình và tôi muốn các nhãn di chuyển sang bên trái tuy nhiên chúng vẫn ở cùng một vị trí trong Cell. Tôi đã cố gắng loại bỏ cell.cdView khỏi giám sát nhưng nó cũng không hoạt động. Tôi đã đính kèm hình ảnh để làm rõ những gì tôi đang về.

tế bào

Tôi biết làm thế nào để làm điều này theo chương trình và tôi không tìm kiếm giải pháp đó. Điều tôi muốn là đặt các ràng buộc trong IB và tôi hy vọng rằng các cuộc phỏng vấn của tôi sẽ di chuyển linh hoạt nếu các chế độ xem khác bị xóa hoặc ẩn. Có thể làm điều này trong IB với bố trí tự động?

.....

Thay đổi thời gian chạy giá trị ràng buộc - kiểm tra câu trả lời
Kampai

Đối với trường hợp cụ thể này, bạn cũng có thể sử dụng UIStackView. khi bạn ẩn cd, các nhãn sẽ chiếm không gian của chúng
Marco Pappalardo

Câu trả lời:


373

Có thể, nhưng bạn sẽ phải làm thêm một chút. Có một vài điều khái niệm cần phải tránh đầu tiên:

  • Các chế độ xem ẩn, mặc dù chúng không vẽ, vẫn tham gia Bố cục tự động và thường giữ lại các khung của chúng , để lại các chế độ xem liên quan khác ở vị trí của chúng.
  • Khi xóa chế độ xem khỏi giám sát của nó, tất cả các ràng buộc liên quan cũng được xóa khỏi phân cấp chế độ xem đó.

Trong trường hợp của bạn, điều này có thể có nghĩa là:

  • Nếu bạn đặt chế độ xem bên trái của mình bị ẩn, các nhãn sẽ giữ nguyên vị trí, vì chế độ xem bên trái vẫn chiếm dung lượng (mặc dù không hiển thị).
  • Nếu bạn xóa chế độ xem bên trái của mình, nhãn của bạn có thể sẽ bị hạn chế một cách mơ hồ, vì bạn không còn bị ràng buộc cho các cạnh trái của nhãn.

Những gì bạn cần làm là thận trọng quá hạn chế nhãn của bạn. Để riêng các ràng buộc hiện tại của bạn (không gian 10pts cho chế độ xem khác), nhưng thêm một ràng buộc khác: làm cho các cạnh bên trái của nhãn của bạn cách xa cạnh trái của giám sát của chúng 10pts với mức độ ưu tiên không bắt buộc (mức ưu tiên cao mặc định có thể sẽ hoạt động tốt).

Sau đó, khi bạn muốn họ di chuyển sang trái, hãy xóa hoàn toàn chế độ xem bên trái. Ràng buộc 10pt bắt buộc đối với chế độ xem bên trái sẽ biến mất cùng với chế độ xem liên quan và bạn sẽ chỉ còn lại một ràng buộc ưu tiên cao mà các nhãn cách xa 10 phút so với giám sát của chúng. Trên thẻ bố trí tiếp theo, điều này sẽ khiến chúng mở rộng sang trái cho đến khi chúng lấp đầy chiều rộng của giám sát nhưng cho khoảng cách của bạn xung quanh các cạnh.

Một cảnh báo quan trọng: nếu bạn muốn nhìn lại hình ảnh bên trái của mình, bạn không chỉ phải thêm nó vào hệ thống phân cấp chế độ xem mà còn phải thiết lập lại tất cả các ràng buộc của nó cùng một lúc. Điều này có nghĩa là bạn cần một cách để đặt ràng buộc khoảng cách 10pt giữa chế độ xem và nhãn của nó bất cứ khi nào chế độ xem đó được hiển thị lại.


8
Mặc dù câu trả lời này chắc chắn sẽ hoạt động, IMO, quá hạn chế để xử lý các trường hợp sử dụng khác nhau dường như là mùi mã - đặc biệt vì bạn sẽ phải thiết lập lại tất cả các ràng buộc cho bất kỳ chế độ xem nào bạn muốn hiển thị lại chế độ xem.
memmons

Theo tôi, đây không phải là con đường để đi. Thay vào đó, bạn nên sử dụng ràng buộc chiều rộng / chiều cao cho chế độ xem mà bạn muốn ẩn.
ullstrm

26
Tôi tôn trọng không đồng ý. Nếu bạn (ví dụ) đặt chiều rộng của chế độ xem thành 0, bạn sẽ gặp hai vấn đề. Đầu tiên, bây giờ bạn có khoảng cách gấp đôi giữa giám sát và chế độ xem hiển thị: |-(space)-[hidden(0)]-(space)-[visible]có hiệu quả |-(2*space)-[visible]. Thứ hai, chế độ xem đó có thể bắt đầu ném các vi phạm ràng buộc tùy thuộc vào cây con và ràng buộc của chế độ xem riêng - bạn không thể đảm bảo rằng bạn có thể tùy ý hạn chế chế độ xem ở độ rộng 0 và để nó tiếp tục hoạt động.
Tim

1
Nếu bạn đang sử dụng chế độ xem với kích thước nội dung nội tại, câu trả lời của Tim dường như là cách duy nhất để đi.
balkoth

Cảm ơn bạn Tim. Tôi đặt ràng buộc là 0 với mức ưu tiên cao hơn để tránh sự không tương thích ràng buộc, nhưng bây giờ tôi nhận ra có vấn đề với khoảng cách gấp đôi. Tôi không gặp phải vấn đề đó bởi vì tôi không bao giờ thể hiện hai quan điểm cùng nhau (trường hợp của tôi |-[otherViews]-[eitherThis][orThis]-|:), nhưng cuối cùng tôi cũng gặp phải vấn đề đó.
Ferran Maylinch

207

Thêm hoặc loại bỏ các ràng buộc trong thời gian chạy là một hoạt động nặng có thể ảnh hưởng đến hiệu suất. Tuy nhiên, có một sự thay thế đơn giản hơn.

Đối với chế độ xem bạn muốn ẩn, hãy thiết lập ràng buộc về chiều rộng. Hạn chế các chế độ xem khác với khoảng cách ngang dẫn đến chế độ xem đó.

Để ẩn, cập nhật .constantgiới hạn độ rộng thành 0.f. Các khung nhìn khác sẽ tự động di chuyển sang trái để đảm nhận vị trí.

Xem câu trả lời khác của tôi ở đây để biết thêm chi tiết:

Làm thế nào để thay đổi các ràng buộc nhãn trong thời gian chạy?


29
Vấn đề duy nhất với giải pháp này là lề bên trái sẽ là gấp đôi so với những gì bạn có thể muốn, vì vậy tôi cũng sẽ cập nhật một trong những hạn chế đó, nhưng ngay cả khi đó tôi nghĩ rằng việc này ít làm việc hơn là loại bỏ cuộc phỏng vấn.
Jose Manuel Sánchez

2
@ skinfan00atg Nếu bạn đang sử dụng chế độ xem với kích thước nội dung nội tại, bạn không thể sử dụng giải pháp này.
balkoth

2
@MaxMacLeod Nếu bạn giảm mức độ ưu tiên ôm nội dung thì bạn không sử dụng kích thước nội dung nội tại, bạn đang sử dụng kích thước được chỉ định bởi ràng buộc.
balkoth

2
@MaxMacLeod Ok, tôi hiểu ý bạn rồi. Bạn cần đặt mức ưu tiên kháng nén thành 0 (không phải là nội dung ôm) trong mã khi bạn muốn ẩn chế độ xem và khi bạn muốn hiển thị lại khôi phục giá trị đó. Ngoài ra, bạn cần thêm một ràng buộc trong trình tạo giao diện để đặt kích thước của chế độ xem thành 0. Không cần phải chạm vào phần tiếp giáp này trong mã.
balkoth

1
điều này thực sự hiệu quả với tôi, cảm ơn bạn rất nhiều
FritzB

87

Đối với những người chỉ hỗ trợ iOS 8+ , có một thuộc tính boolean mới hoạt động . Nó sẽ giúp kích hoạt chỉ các ràng buộc cần thiết một cách linh hoạt

Ổ cắm ràng buộc PS phải mạnh , không yếu

Ví dụ:

@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
}

Ngoài ra, để sửa lỗi trong bảng phân cảnh, bạn cần bỏ chọn Installedhộp kiểm cho một trong những ràng buộc này.

UIStackView (iOS 9+)
Thêm một tùy chọn nữa là bao bọc quan điểm của bạn UIStackView. Khi chế độ xem bị ẩn UIStackViewsẽ tự động cập nhật bố cục


hoạt động một phần hoạt động. Nhưng nếu tôi sử dụng nó bên trong một tế bào có thể tái sử dụng, từ kích hoạt đến hủy kích hoạt, sẽ hoạt động, nhưng không phải để hủy kích hoạt. Có ý kiến ​​gì không? Hoặc bạn có thể cung cấp một ví dụ có thể?
Aoke Li

10
Nó xảy ra bởi vì các ràng buộc đã hủy kích hoạt không được tải hoặc giải phóng. Cửa hàng ràng buộc của bạn phải mạnh mẽ, không yếu đuối
Silmaril

Chúng ta có thể tìm thấy tài sản "hoạt động" đó ở đâu?
Lakshmi Reddy


Có vẻ như quá hạn chế + thiết lập hoạt động ràng buộc có thể là câu trả lời hợp lý nhất.
Ting Yi Shih

68

UIStackViewtự động định vị lại các chế độ xem của nó khi thuộc hiddentính được thay đổi trên bất kỳ lượt xem nào của nó (iOS 9+).

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

Chuyển đến 11:48 trong video WWDC này để xem bản demo:

Bí ẩn về bố cục tự động, Phần 1


Tôi ẩn chế độ xem ngăn xếp lồng nhau và toàn bộ chế độ xem ngăn xếp biến mất.
Ian Warburton

5
Đây phải là câu trả lời được chấp nhận. Theo khuyến cáo của Apple về wwdc 2015 về thiết kế xây dựng giao diện.
thibaut noah

@thibautnoah Và còn iOS 8- hỗ trợ thì sao?
bagage

5
@bagage Trừ khi bạn là facebook hoặc google, bạn có thể bỏ nó. Với phạm vi bảo hiểm beyong iOS 9, bạn sẽ hỗ trợ hơn 90% thiết bị, quá đủ. Hỗ trợ dưới đây sẽ làm tê liệt quá trình phát triển của bạn và ngăn bạn sử dụng các tính năng mới nhất imo
thibaut noah

16

Dự án của tôi sử dụng một @IBDesignablelớp con tùy chỉnh UILabel(để đảm bảo tính nhất quán về màu sắc, phông chữ, nội dung, v.v.) và tôi đã thực hiện một số thứ như sau:

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

Điều này cho phép lớp con nhãn tham gia vào Bố cục tự động, nhưng không có khoảng trống khi ẩn.


13

Đối với nhân viên Google: dựa trên câu trả lời của Max, để giải quyết vấn đề đệm mà nhiều người nhận thấy tôi chỉ đơn giản là tăng chiều cao của nhãn và sử dụng chiều cao đó làm dấu phân cách thay vì đệm thực tế. Ý tưởng này có thể được mở rộng cho bất kỳ kịch bản nào có chứa các khung nhìn.

Đây là một ví dụ đơn giản:

Ảnh chụp màn hình IB

Trong trường hợp này, tôi ánh xạ chiều cao của nhãn Tác giả tới mức phù hợp IBOutlet:

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

và khi tôi đặt chiều cao của ràng buộc thành 0.0f, chúng tôi sẽ giữ "phần đệm", vì chiều cao của nút Play cho phép điều đó.


Đối với những người mới biết NSLayoutConstrainttôi tin rằng bạn muốn cập nhật constanttài sản của bạn authorLabelHeight.
Kyle

8

kết nối ràng buộc giữa uiview và nhãn dưới dạng IBOutlet và đặt thành viên ưu tiên thành giá trị ít hơn khi được đặt ẩn = CÓ


3
Bạn không thể điều chỉnh mức độ ưu tiên của NSLayoutConstraint sau khi được thiết lập; bạn phải loại bỏ và tập hợp lại một ràng buộc mới với mức độ ưu tiên khác.
Tim

7
Tôi đã có phương pháp này để làm việc. Tôi có một trường hợp sử dụng nhãn và nút, nơi tôi cần ẩn nút và mở rộng nhãn. Tôi có hai ràng buộc, một ràng buộc ban đầu với ưu tiên 751 và một ràng buộc với 750. Sau đó, khi tôi ẩn nút, tôi lật các ưu tiên và độ dài của nhãn phát triển. Cần lưu ý rằng nếu bạn cố gắng tạo mức ưu tiên cao hơn 1000, bạn sẽ gặp lỗi "Không hỗ trợ ưu tiên từ yêu cầu thành không ràng buộc cài đặt (hoặc ngược lại).". Vì vậy, đừng và bạn có vẻ ổn. Xcode 5.1 / viewDidLoad.
John Bushnell

8

Điều cuối cùng tôi làm là tạo ra 2 xibs. Một với góc nhìn bên trái và một không có nó. Tôi đã đăng ký cả hai trong bộ điều khiển và sau đó quyết định sử dụng trong cellForRowAtIndexPath.

Họ sử dụng cùng một lớp UITableViewCell. Nhược điểm là có một số sao chép nội dung giữa các xib, nhưng các ô này khá cơ bản. Ưu điểm là tôi không có nhiều mã để quản lý xóa chế độ xem, cập nhật các ràng buộc, v.v.

Nhìn chung, đây có lẽ là một giải pháp tốt hơn vì chúng là các bố cục kỹ thuật khác nhau và do đó nên có các xib khác nhau.

[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

Trong trường hợp này, tôi ánh xạ chiều cao của nhãn Tác giả tới một IBOutlet thích hợp:

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

và khi tôi đặt chiều cao của ràng buộc thành 0,0f, chúng tôi sẽ giữ "phần đệm", vì chiều cao của nút Play cho phép điều đó.

cell.authorLabelHeight.constant = 0;

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


6

Sử dụng hai UIStackView Ngang và Dọc, khi một số chế độ xem phụ trong ngăn xếp bị ẩn, các lần xem khác của ngăn xếp sẽ được di chuyển, sử dụng Phân phối -> Điền chủ yếu cho ngăn xếp Dọc với hai UILabels và cần thiết lập các chiều rộng và chiều cao cho UIView đầu tiênnhập mô tả hình ảnh ở đây


2

Hãy thử điều này, tôi đã thực hiện dưới đây mã,

Tôi có một Chế độ xem trên ViewContoder trong đó đã thêm ba chế độ xem khác, Khi bất kỳ chế độ xem nào bị ẩn, hai chế độ xem khác sẽ di chuyển, Thực hiện theo các bước bên dưới. ,

Tập tin 1.ViewControll.h

#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.ViewControll.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

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Hy vọng vì vậy logic này sẽ giúp một số người.


1

Trong trường hợp của tôi, tôi đặt hằng số giới hạn chiều cao thành 0.0fvà cũng đặt thuộc hiddentính thành YES.

Để hiển thị chế độ xem (với các cuộc phỏng vấn) một lần nữa tôi đã làm ngược lại: Tôi đặt hằng số chiều cao thành giá trị khác không và đặt thuộc hiddentính thành NO.


1

Tôi sẽ sử dụng stackview ngang. Nó có thể loại bỏ khung khi ẩn phụ.

Trong hình ảnh bên dưới, chế độ xem màu đỏ là vùng chứa thực tế cho nội dung của bạn và có khoảng trống kéo dài 10 phút với giám sát màu cam (ShowHideView), sau đó chỉ cần kết nối ShowHideView với IBOutlet và hiển thị / ẩn / xóa nó theo chương trình.

  1. Đây là khi chế độ xem được hiển thị / cài đặt.

nhìn thấy được

  1. Đây là khi chế độ xem bị ẩn / không được cài đặt.

Chế độ xem bị ẩn / xóa


1

Đây là giải pháp khác của tôi sử dụng ràng buộc ưu tiên. Ý tưởng được đặt chiều rộng thành 0.

  1. tạo chế độ xem container (màu cam) và đặt chiều rộng. nhập mô tả hình ảnh ở đây

  2. tạo chế độ xem nội dung (màu đỏ) và đặt khoảng trống 10pt thành giám sát (màu cam). Lưu ý các ràng buộc không gian theo dõi, có 2 ràng buộc theo dõi với mức độ ưu tiên khác nhau. Thấp (= 10) và Cao (<= 10). Điều này rất quan trọng để tránh sự mơ hồ. nhập mô tả hình ảnh ở đây

  3. Đặt chiều rộng của khung nhìn màu cam thành 0 để ẩn chế độ xem. nhập mô tả hình ảnh ở đây


0

Như no_scene đã đề xuất, bạn chắc chắn có thể làm điều này bằng cách thay đổi mức độ ưu tiên của ràng buộc khi chạy. Điều này dễ dàng hơn nhiều đối với tôi vì tôi có nhiều hơn một chế độ chặn sẽ bị xóa.

Đây là đoạn trích sử dụng ReactiveCocoa:

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

Trong trường hợp điều này giúp được ai đó, tôi đã xây dựng một lớp trợ giúp để sử dụng các ràng buộc định dạng trực quan . Tôi đang sử dụng nó trong ứng dụng hiện tại của tôi.

AutolayoutHelper

Nó có thể phù hợp với nhu cầu của tôi, nhưng bạn có thể thấy nó hữu ích hoặc bạn có thể muốn sửa đổi nó và tạo người trợ giúp của riêng bạn.

Tôi phải cảm ơn Tim vì câu trả lời của anh ấy ở trên , câu trả lời này về UIScrollView và cả hướng dẫn này .


0

Đây là cách tôi sẽ sắp xếp lại các uiview của mình để có được giải pháp của bạn:

  1. Kéo thả một UIImageView và đặt nó sang trái.
  2. Kéo thả một UIView và đặt nó ở bên phải của UIImageView.
  3. Kéo thả hai UILabels bên trong UIView có các ràng buộc hàng đầu và theo sau bằng không.
  4. Đặt ràng buộc hàng đầu của UIView chứa 2 nhãn thành giám sát thay vì UIImagView.
  5. NẾU UIImageView bị ẩn, đặt hằng số ràng buộc hàng đầu thành 10 px thành giám sát. ELSE, đặt hằng số ràng buộc hàng đầu là 10 px + UIImageView. Thong + 10 px.

Tôi đã tạo ra một quy tắc ngón tay cái của riêng tôi. Bất cứ khi nào bạn phải ẩn / hiển thị bất kỳ uiview nào có các ràng buộc có thể bị ảnh hưởng, hãy thêm tất cả các cuộc phỏng vấn bị ảnh hưởng / phụ thuộc vào một uiview và cập nhật liên tục ràng buộc hàng đầu / theo dõi / trên / dưới của nó theo chương trình.


0

Đây là một câu hỏi cũ nhưng tôi vẫn hy vọng nó sẽ giúp. Đến từ Android, trong nền tảng này, bạn có một phương pháp tiện dụng isVisibleđể ẩn nó khỏi chế độ xem nhưng cũng không có khung được xem xét khi tự động thanh toán vẽ chế độ xem.

sử dụng tiện ích mở rộng và "mở rộng" uiview, bạn có thể thực hiện một chức năng tương tự trong ios (không chắc tại sao nó không có trong UIKit) ở đây một triển khai trong swift 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

cách thích hợp để làm điều đó là vô hiệu hóa các ràng buộc với isActive = false. tuy nhiên lưu ý rằng việc vô hiệu hóa một ràng buộc sẽ loại bỏ và giải phóng nó, vì vậy bạn phải có các cửa hàng mạnh cho chúng.


0

Giải pháp đơn giản nhất là sử dụng UIStackView (ngang). Thêm vào chế độ xem ngăn xếp: chế độ xem thứ nhất và chế độ xem thứ hai với nhãn. Sau đó đặt thuộc tính isHidden của chế độ xem đầu tiên thành false. Tất cả các ràng buộc sẽ được tính toán và cập nhật tự động.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.