Lề khoảng cách UICollectionView


181

Tôi có một UICollectionViewcái cho thấy hình ảnh. Tôi đã tạo ra bộ sưu tập bằng cách sử dụng UICollectionViewFlowLayout. Nó hoạt động tốt nhưng tôi muốn có khoảng cách trên lề. Có thể làm điều đó bằng cách sử dụng UICollectionViewFlowLayouthoặc tôi phải tự thực hiện UICollectionViewLayout?

Câu trả lời:


331

Bạn có thể sử dụng collectionView:layout:insetForSectionAtIndex:phương thức cho UICollectionViewhoặc đặt thuộc sectionInsettính của UICollectionViewFlowLayoutđối tượng được đính kèm UICollectionView:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(top, left, bottom, right);
}

hoặc là

UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setSectionInset:UIEdgeInsetsMake(top, left, bottom, right)];

Đã cập nhật cho Swift 5

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
       return UIEdgeInsets(top: 25, left: 15, bottom: 0, right: 5)
    }

35
Tôi dường như không làm cho các phần bên trái và bên phải hoạt động khi sử dụng bố cục luồng dọc ...
John

1
Bây giờ ghi đè phương thức partInset của UICollectionViewFlowLayout được phân lớp cũng không có hiệu lực. Thiết lập thuộc tính được mô tả dưới đây hoạt động.
Dren

4
Lưu ý: nhớ thêm UICollectionViewDelegateFlowLayoutvào danh sách đại biểu ViewContoder của bạn để sử dụng phương thứcinsetForSectionAtIndex
David Douglas

98

Thiết lập các phần tử trong Trình tạo giao diện như hiển thị trong ảnh chụp màn hình bên dưới

Cài đặt phần chèn cho UICollectionView

Sẽ dẫn đến một cái gì đó như thế này:

Một ô xem bộ sưu tập với phần chèn


2
Câu trả lời tuyệt vời, chỉ muốn chỉ ra rằng bạn cũng sẽ phải chơi với khoảng cách tối thiểu để phần chèn hoạt động tốt.
Smit Yash

75

Để thêm khoảng cách trên toàn bộ UICollectionView :

UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);

Để chơi với khoảng cách giữa các thành phần của cùng một hàng (cột nếu bạn cuộn theo chiều ngang) và kích thước của chúng:

flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;

5
Điều này hoạt động, nhưng collection.collectionViewLayoutcần một dàn diễn viên như trong ví dụ của @Pooja: UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
jwj

Đúc trong swiftif let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
emily

41

Swift 4

    let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout // If you create collectionView programmatically then just create this flow by UICollectionViewFlowLayout() and init a collectionView by this flow.

    let itemSpacing: CGFloat = 3
    let itemsInOneLine: CGFloat = 3
    flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1) //collectionView.frame.width is the same as  UIScreen.main.bounds.size.width here.
    flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
    flow.minimumInteritemSpacing = 3
    flow.minimumLineSpacing = 3

EDIT XCode 11.4 và nhanh chóng 5

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

không hoạt động. Sử dụng dưới đây hoạt động.

let flow = UICollectionViewFlowLayout()

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


Có cách nào để đặt màu cho khoảng cách không?
Martín Daniel

1
@ MartínDaniel Chỉ cần đặt backgroundColorcủa collectionView. Hoặc bất cứ điều gì siêu xem.
William Hu

1
nhưng không có lề ở các cạnh
user924

@ user924 Lợi nhuận ở các cạnh có thể được đặt bằng UIEdgeInsets (top: left: bottom: right :). Nếu cuộn theo chiều dọc, đặt phần bên trái / bên phải. Nếu cuộn theo chiều ngang, hãy đặt phần trên và dưới.
Marcy

40

Chỉ cần sửa một số thông tin sai trong trang này:

1- MinimalInteritemSpaces : Khoảng cách tối thiểu để sử dụng giữa các mục trong cùng một hàng.

Giá trị mặc định: 10.0.

(Đối với lưới cuộn theo chiều dọc, giá trị này biểu thị khoảng cách tối thiểu giữa các mục trong cùng một hàng.)

2- MinimalLineSpaces : Khoảng cách tối thiểu để sử dụng giữa các dòng của các mục trong lưới.

Tham chiếu: http://developer.apple.com/l Library / ios / # document / uikit / report / UollollViewViewFlowLayout_group / Reference / Reference.html


2
Điều này dường như không ảnh hưởng đến khoảng cách giữa các phần, chỉ giữa các mục trong cùng một phần?
Crashalot

@Crashalot - bạn có chắc là bạn không có nghĩa là MinimalLineSpaces? tức là mỗi dòng tế bào? Ngoài ra còn có các tùy chọn cho Phần nội dung nếu bạn thực sự đang sử dụng các phần.
Chucky

Điều này làm việc cho tôi làm điều đó thông qua giao diện bảng phân cảnh. Tôi đang tìm kiếm một giải pháp cho quan điểm bộ sưu tập chỉ ngang. Cảm ơn +10
kemicofa ghost

9

Swift hiện đại, tính toán bố cục tự động

Mặc dù chủ đề này đã chứa một loạt các câu trả lời hữu ích, tôi muốn thêm một phiên bản Swift hiện đại , dựa trên câu trả lời của William Hu. Nó cũng cải thiện hai điều:

  • Khoảng cách giữa các dòng khác nhau sẽ luôn khớp với khoảng cách giữa các mục trong cùng một dòng.
  • Bằng cách đặt chiều rộng tối thiểu, mã sẽ tự động tính toán số lượng mục trong một hàng và áp dụng kiểu đó cho bố cục luồng.

Đây là mã:

// Create flow layout
let flow = UICollectionViewFlowLayout()

// Define layout constants
let itemSpacing: CGFloat = 1
let minimumCellWidth: CGFloat = 120
let collectionViewWidth = collectionView!.bounds.size.width

// Calculate other required constants
let itemsInOneLine = CGFloat(Int((collectionViewWidth - CGFloat(Int(collectionViewWidth / minimumCellWidth) - 1) * itemSpacing) / minimumCellWidth))
let width = collectionViewWidth - itemSpacing * (itemsInOneLine - 1)
let cellWidth = floor(width / itemsInOneLine)
let realItemSpacing = itemSpacing + (width / itemsInOneLine - cellWidth) * itemsInOneLine / max(1, itemsInOneLine - 1))

// Apply values
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
flow.itemSize = CGSize(width: cellWidth, height: cellWidth)
flow.minimumInteritemSpacing = realItemSpacing
flow.minimumLineSpacing = realItemSpacing

// Apply flow layout
collectionView?.setCollectionViewLayout(flow, animated: false)

Nếu itemsInOneLinelà 1 thì điều này sẽ dẫn đến NaN do chia cho số 0 ở đây:itemsInOneLine / (itemsInOneLine - 1)
TylerJames

1
@TylerJames Cảm ơn! Tôi đã điều chỉnh mã để khắc phục sự cố;)
fredpi

8

sử dụng setMinimumLineSpacing:setMinimumInteritemSpacing:trên UICollectionViewFlowLayout-Oject.


Không, nó không hoạt động, như mong đợi. setMinimumLineSpaces là: Khoảng cách tối thiểu để sử dụng giữa các mục trong cùng một hàng. Và setMinimumInteritemSpaces là: Khoảng cách tối thiểu để sử dụng giữa các dòng của các mục trong lưới. Câu hỏi của tôi là về lề không phải là không gian giữa các yếu tố. ví dụ. Khoảng cách bên trái và trên cùng của phần tử đầu tiên.
Mert

giả sử một srollDirection dọc, bạn có thể sử dụng contentInset cho khoảng cách trên và dưới của hàng đầu tiên và cuối cùng. Ngoài ra, bạn có thể thêm lề của bạn trong các tế bào của bạn.
Jonathan Cichon

8

Sử dụng collectionViewFlowLayout.sectionInsethoặc collectionView:layout:insetForSectionAtIndex:là chính xác.

Tuy nhiên, nếu bộ sưu tập của bạn có nhiều phần và bạn muốn thêm lề vào toàn bộ bộ sưu tập, tôi khuyên bạn nên sử dụng scrollView contentInset:

UIEdgeInsets collectionViewInsets = UIEdgeInsetsMake(50.0, 0.0, 30.0, 0.0);
self.collectionView.contentInset = collectionViewInsets;
self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(collectionViewInsets.top, 0, collectionViewInsets.bottom, 0);

5

Để đặt không gian giữa CollectionItemcác s sử dụng này

viết hai dòng này trong viewdidload

UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)

5

Đặt thuộc insetForSectionAttính của UICollectionViewFlowLayoutđối tượng gắn liền với của bạnUICollectionView

Đảm bảo thêm giao thức này

UICollectionViewDelegateFlowLayout

Nhanh

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets (top: top, left: left, bottom: bottom, right: right)
    }

Mục tiêu - C

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(top, left, bottom, right);
}

2

Trong Mục tiêu-C

CGFloat spacing = 5;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)_habbitCollectionV.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(0, spacing, 0, spacing);
CGFloat itemsPerRow = 2;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat oneMore = itemsPerRow + 1;
CGFloat width = screenRect.size.width - spacing * oneMore;
CGFloat height = width / itemsPerRow;

flow.itemSize = CGSizeMake(floor(height), height);
flow.minimumInteritemSpacing = spacing;
flow.minimumLineSpacing = spacing;

Tất cả bạn phải làm là thay đổi giá trị itemsPerRow và nó sẽ cập nhật số lượng mục trên mỗi hàng tương ứng. Hơn nữa, bạn có thể thay đổi giá trị khoảng cách nếu bạn muốn khoảng cách chung nhiều hơn hoặc ít hơn.

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


1
Thật tuyệt ... nó hoạt động hoàn hảo.
sohil

1

Để thêm lề vào các ô đã chỉ định, bạn có thể sử dụng bố cục luồng tùy chỉnh này. https://github.com/voyages-sncf-technology/VSCollectionViewCellInsetFlowLayout/

extension ViewController : VSCollectionViewDelegateCellInsetFlowLayout 
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForItemAt indexPath: IndexPath) -> UIEdgeInsets {
        if indexPath.item == 0 {
            return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
        }
        return UIEdgeInsets.zero
    }
}

0

Trong swift 4 và autoLayout, bạn có thể sử dụng phầnInset như thế này:

let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.itemSize = CGSize(width: (view.frame.width-40)/2, height: (view.frame.width40)/2) // item size
        layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10) // here you can add space to 4 side of item
        collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) // set layout to item
        collectionView?.register(ProductCategoryCell.self, forCellWithReuseIdentifier: cellIdentifier) // registerCell
        collectionView?.backgroundColor = .white // background color of UICollectionView
        view.addSubview(collectionView!) // add UICollectionView to view

-1

Để thêm phân tách 10px giữa mỗi phần, chỉ cần viết này

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);

khi sử dụng UICollectionReabilitiesView loại UICollectionEuityKindSectionFooter, giải pháp của bạn sẽ không hoạt động
Pratik Jamariya

-1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {       
         return UIEdgeInsetsMake(7, 10, 5, 10);    
   }
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.