Cách thêm khoảng cách giữa UITableViewCell


182

Có cách nào để thêm khoảng cách giữa UITableViewCell?

Tôi đã tạo một bảng và mỗi ô chỉ chứa một hình ảnh. Hình ảnh được gán cho ô như thế này:

cell.imageView.image = [myImages objectAtIndex:indexPath.row];

nhưng điều này làm cho hình ảnh được phóng to và vừa với toàn bộ tế bào và không có khoảng cách giữa các hình ảnh.

Hoặc giả sử theo cách này, chiều cao của hình ảnh là 50 và tôi muốn thêm 20 khoảng cách giữa các hình ảnh. Có cách nào để thực hiện điều này?


1
Đối với Swift 2.2, hãy xem câu trả lời của tôi tại đây: stackoverflow.com/a/37673417/2696626
ibrahimyilmaz

Câu trả lời:


160

Phiên bản Swift

Đã cập nhật cho Swift 3

Câu trả lời này có phần chung chung hơn câu hỏi ban đầu vì lợi ích của người xem trong tương lai. Đây là một ví dụ bổ sung cho ví dụ UITableView cơ bản cho Swift .

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

Tổng quat

Ý tưởng cơ bản là tạo một phần mới (chứ không phải là một hàng mới) cho mỗi mục mảng. Các phần sau đó có thể được đặt cách nhau bằng chiều cao tiêu đề của phần.

Làm thế nào để làm nó

  • Thiết lập dự án của bạn như được mô tả trong ví dụ UITableView cho Swift . (Nghĩa là thêm một UITableViewvà nối tableViewổ cắm vào Bộ điều khiển xem).

  • Trong Trình tạo giao diện, thay đổi màu nền của chế độ xem chính thành màu xanh nhạt và UITableViewmàu nền để xóa.

  • Thay thế mã ViewControll.swift bằng cách sau.

ViewControll.swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // These strings will be the data for the table view cells
    let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
    
    let cellReuseIdentifier = "cell"
    let cellSpacingHeight: CGFloat = 5
    
    @IBOutlet var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // These tasks can also be done in IB if you prefer.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }
    
    // MARK: - Table View delegate methods
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.animals.count
    }
    
    // There is just one row in every section
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    // Set the spacing between sections
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return cellSpacingHeight
    }
    
    // Make the background color show through
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView()
        headerView.backgroundColor = UIColor.clear
        return headerView
    }
    
    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
        
        // note that indexPath.section is used rather than indexPath.row
        cell.textLabel?.text = self.animals[indexPath.section]
        
        // add border and color
        cell.backgroundColor = UIColor.white
        cell.layer.borderColor = UIColor.black.cgColor
        cell.layer.borderWidth = 1
        cell.layer.cornerRadius = 8
        cell.clipsToBounds = true
        
        return cell
    }
    
    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // note that indexPath.section is used rather than indexPath.row
        print("You tapped cell number \(indexPath.section).")
    }
}

Lưu ý rằng indexPath.sectionđược sử dụng thay vì indexPath.rowđể có được các giá trị phù hợp cho các thành phần mảng và vị trí nhấn.

Làm thế nào bạn có được phần đệm thêm / không gian bên phải và bên trái?

Tôi hiểu nó giống như cách bạn thêm khoảng cách vào bất kỳ chế độ xem nào. Tôi đã sử dụng các ràng buộc bố trí tự động. Chỉ cần sử dụng công cụ ghim trong Trình tạo giao diện để thêm khoảng cách cho các ràng buộc hàng đầu và dấu.


Xin chào, tôi đã tự hỏi nếu điều này là có thể mà không chuyển đổi tất cả các hàng của bạn thành các phần. Tôi có đường viền trên mỗi bảngViewCell, vì vậy việc tăng chiều cao sẽ không giúp ích gì. Tôi có rất nhiều tùy chỉnh với di động của mình và tôi không muốn chuyển đổi nó thành các phần. Cảm ơn!
Ujjwal-Nadhani

3
@ user2901306, ban đầu tôi cũng do dự khi sử dụng phương pháp này, vì cảm thấy như tôi có thể chỉ cần sử dụng các hàng và tăng lề hoặc một cái gì đó. Tuy nhiên, tôi đã không tìm ra cách để làm điều đó và phương pháp này hoạt động khá tốt. Bạn không phải thay đổi các tùy chỉnh trên di động của bạn. Về cơ bản, bạn chỉ cần thêm numberOfSectionsInTableViewreturn 1cho số lượng hàng. Sau đó sử dụng indexPath.sectionđể có được chỉ số tế bào hiện tại. Hãy thử một lần. Tôi nghĩ bạn sẽ khám phá ra rằng bạn không cần phải thực hiện nhiều thay đổi cho thiết lập hiện tại của mình. Điều này chắc chắn dễ dàng hơn phân lớp.
Suragch

Sử dụng cell.layer.xxx trong cellForRow có thể mang lại cho bạn hiệu suất cao. Tốt hơn nên đặt các giá trị này trong XIB
Abhishek Bedi

@AbhishekBedi, tôi luôn thấy các layerthao tác khá nhanh. Bạn đang nói điều này bởi vì bạn nhận thấy một hit hiệu suất, hoặc như là một thực hành tốt nói chung? Ngay cả khi bạn đặt chúng trong XIB, chúng vẫn phải được đặt khi ô được tạo.
Suragch

1
@FateNuller, tôi không đồng ý với bạn. Câu trả lời của Husam có vẻ khá tốt.
Suragch

150

Giải pháp dễ dàng của tôi bằng Swift :

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

    contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}

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


11
Giải pháp tốt đẹp. Trong trường hợp bất cứ ai có vấn đề, tôi phải gọi super.layoutSubviews()trước để đảm bảo toàn bộ khung nhìn được đặt đúng trước khi đặt khung của nó.
ruttopia

@Husam Giải pháp của bạn đã làm việc cho tôi. Nhưng tôi có một vấn đề khi chọn ô. Tôi đã đặt đường viền cho contentView và bất cứ khi nào tôi chọn ô, đường viền sẽ nhỏ hơn. Làm thế nào tôi có thể sửa chữa nó?
Bad_Developer

@SonHoang Bạn có thể cần ghi đè didSetcho selectedbiến và gọi layoutSubviews()bên trong!
Husam

1
Này, Husam. Cảm ơn giải pháp tuyệt vời. Đừng nói với tôi cách thay đổi màu của nội dung được thêm vào giữa các ô?
A.Kant

1
Đây là một giải pháp tốt hơn nhiều so với câu trả lời được chấp nhận. Câu trả lời được chấp nhận có gần 100 dòng mã và đây chỉ là một dòng. Đáng kinh ngạc.
YungGun

135

Cách tôi đạt được thêm khoảng cách giữa các ô là tạo numberOfSections = "Số mảng của bạn" và làm cho mỗi phần chỉ chứa một hàng. Và sau đó xác định tiêu đề và chiều cao của nó.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return yourArry.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return cellSpacingHeight;
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *v = [UIView new];
    [v setBackgroundColor:[UIColor clearColor]];
    return v;
}

22
Điều này làm việc tuyệt vời. Tôi đã phải thay đổi cellForRowAtIndexPath một chút, không phải mảng bình thường [indexPath.row] mà là mảng [indexPath.section]. Nếu không, nó sẽ hiển thị mục đầu tiên của mảng trong tất cả các phần.
Tom Spee

@TomSpee - Bạn đã giải quyết vấn đề đó như thế nào trong cellForRowAtIndexPath?

5
@TKutal - Giống như mã thông thường trong cellForRowAtIndexPath nhưng thay đổi indexPath.row thành indexPath.section
Tom Spee

Mặc dù điều này thực hiện được những gì người hỏi mong muốn, tôi không tin rằng Apple sẽ đề xuất phương pháp này. Sửa lỗi cho tôi nếu tôi sai, nhưng tôi tin rằng "các phần" có nghĩa là để phân tách hợp lý các "phần" dữ liệu mà bạn đại diện trong bảng của mình. Bạn không nên sử dụng "phần" để định kiểu khoảng trắng ở giữa mỗi ô dữ liệu, nếu không tất cả sẽ được hiển thị trong một phần. Tôi nghĩ rằng cách tiếp cận tốt hơn, mặc dù khó khăn hơn, sẽ là phân lớp UITableViewCell và mô phỏng trình phân tách chế độ xem bảng bằng cách thêm chế độ xem vào dưới cùng của ô.
FateNuller

2
Sau đó, Apple không nên phàn nàn mà tạo ra một phương pháp thuận tiện để thay đổi không gian giữa các hàng.
Arnie Schwarzvogel

44

Tôi cần phải thực hiện cùng một khái niệm về việc có UITableCells có "khoảng trống" giữa chúng. Vì bạn không thể thêm không gian giữa các ô theo nghĩa đen, bạn có thể giả mạo nó bằng cách thao tác chiều cao ô của UITableView và sau đó thêm UIView vào contentView của ô của bạn. Đây là ảnh chụp màn hình nguyên mẫu tôi đã làm trong một dự án thử nghiệm khác khi tôi đang mô phỏng điều này:

Khoảng cách giữa các UITableViewCells

Đây là một số mã (Lưu ý: có rất nhiều giá trị được mã hóa cứng cho mục đích trình diễn)

Đầu tiên, tôi cần thiết lập heightForRowAtIndexPathđể cho phép các độ cao khác nhau trên UITableViewCell.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSString *text = [self.newsArray  objectAtIndex:[indexPath row]];
    if ([text isEqual:@"December 2012"])
    {
        return 25.0;
    }

    return 80.0;
}

Tiếp theo, tôi muốn thao tác giao diện của UITableViewCells để tôi thực hiện điều đó trong willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathphương thức.

- (void)tableView:(UITableView *)tableView willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (cell.IsMonth)
    {
        UIImageView *av = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 20, 20)];
        av.backgroundColor = [UIColor clearColor];
        av.opaque = NO;
        av.image = [UIImage imageNamed:@"month-bar-bkgd.png"];
        UILabel *monthTextLabel = [[UILabel alloc] init];
        CGFloat font = 11.0f;
        monthTextLabel.font = [BVFont HelveticaNeue:&font];

        cell.backgroundView = av;
        cell.textLabel.font = [BVFont HelveticaNeue:&font];
        cell.textLabel.textColor = [BVFont WebGrey];
    }


    if (indexPath.row != 0)
    {
        cell.contentView.backgroundColor = [UIColor clearColor];
        UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,70)];
        whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
        whiteRoundedCornerView.layer.masksToBounds = NO;
        whiteRoundedCornerView.layer.cornerRadius = 3.0;
        whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
        whiteRoundedCornerView.layer.shadowOpacity = 0.5;
        [cell.contentView addSubview:whiteRoundedCornerView];
        [cell.contentView sendSubviewToBack:whiteRoundedCornerView];

    }
}

Lưu ý rằng tôi đã tạo cho WhiteRoundedCornerView chiều cao 70.0 và đó là nguyên nhân gây ra không gian mô phỏng vì chiều cao của ô thực sự là 80.0 nhưng contentView của tôi là 70.0 mang lại vẻ ngoài.

Có thể có nhiều cách khác để thực hiện điều này thậm chí còn tốt hơn nhưng đó chỉ là cách tôi tìm ra cách thực hiện. Tôi hy vọng nó có thể giúp đỡ người khác.


Chỉ là một FYI, đối với số lượng ô rất lớn, bạn sẽ muốn đặt chế độ xem nội dung bên trong lớp con ô thay vì willDisplayCell. Hiệu suất bắt đầu đạt được thành công lớn khi thực hiện theo cách này khi bạn thêm nhiều ô vào hàng đợi
BBH1023

@ BBH1023 Lớp bóng nhân lên mỗi lần khung nhìn xuất hiện khi điều hướng qua lại để xem nhanh. Làm thế nào bạn sẽ đề nghị hủy bỏ mà ra nếu nó đã được áp dụng một lần
soulshined

để riêng tư để thêm bóng tối làm điều này: thẻ NSInteger = 120; if (indexPath.row! = 0) {if (cell.tag! = 120) {cell.contentView.backgroundColor = [UIColor clearColor]; ... [cell.contentView sendSubviewToBack: whiteRoundedCornerView]; ô.tag = thẻ; }}
user3001228 15/03/2015

24

Bạn sẽ phải đặt khung cho hình ảnh của bạn. Mã chưa được kiểm tra là

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);

2
Chỉ cần thử nghiệm với backgroundView và đây là giải pháp làm việc đơn giản nhất
Sam

2
Chỉ cần đảm bảo rằng bạn gọi mã này layoutSubviewsnếu bạn đang phân lớpUITableViewCell
Mazyod

30
@ NicoHämäläinen Chà, tôi đã phát triển hơn 20 ứng dụng trong ba năm qua và tôi LUÔN LUÔN phân lớp UITableViewCellđể có được kết quả tôi cần :) ... Phân lớp UITableViewCellrất phổ biến.
Mazyod

1
@ NicoHämäläinen không có gì sai với phân lớp UITableViewCell. Khi bạn đang tạo tùy chỉnh, UITableViewCellsbạn nên phân lớp UITableViewCell.
Popeye

1
@ NicoHämäläinen bạn nên cập nhật bình luận của bạn sau đó. Mọi người có xu hướng lấy thông tin và không đọc thêm. Vì trang web này là một tài nguyên tuyệt vời và các nhà phát triển có xu hướng tin tưởng vào sự thật mà họ thấy ở đây, nó có thể khiến họ lầm tưởng những điều khủng khiếp .. chỉ hai đồng tiền của tôi. Có lẽ tôi bị cuồng loạn
chrs

11

Tôi đã ở trong cùng một chiếc thuyền. Lúc đầu, tôi đã thử chuyển sang các phần, nhưng trong trường hợp của tôi, nó đã khiến tôi đau đầu hơn tôi nghĩ ban đầu, vì vậy tôi đã tìm kiếm một giải pháp thay thế. Để tiếp tục sử dụng các hàng (và không gây rối với cách bạn truy cập dữ liệu mô hình của mình), đây là những gì hiệu quả với tôi chỉ bằng cách sử dụng mặt nạ :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
    let verticalPadding: CGFloat = 8

    let maskLayer = CALayer()
    maskLayer.cornerRadius = 10    //if you want round edges
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.frame = CGRect(x: cell.bounds.origin.x, y: cell.bounds.origin.y, width: cell.bounds.width, height: cell.bounds.height).insetBy(dx: 0, dy: verticalPadding/2)
    cell.layer.mask = maskLayer
}

Tất cả những gì bạn phải làm là làm cho chiều cao của ô lớn hơn cùng giá trị như bạn mong muốn verticalPadding, sau đó sửa đổi bố cục bên trong của bạn để bất kỳ chế độ xem nào có khoảng cách đến các cạnh của ô có cùng khoảng cách tăng lên verticalPadding/2. Nhược điểm nhỏ: bạn có phần verticalPadding/2đệm ở cả trên cùng và dưới cùng của bảng Xem, nhưng bạn có thể nhanh chóng khắc phục điều này bằng cách cài đặt tableView.contentInset.bottom = -verticalPadding/2tableView.contentInset.top = -verticalPadding/2. Hy vọng điều này sẽ giúp ai đó!


1
Hoạt động trong Swift 5 cũng vậy.
LondonGuy

1
Câu trả lời tốt nhất!! Cảm ơn bạn. Nếu sử dụng một ô tùy chỉnh, thì nó sẽ hoạt động trong "ghi đè func awakeFromNib ()"
cây_are_great

10

Tôi nghĩ giải pháp đơn giản nhất nếu bạn chỉ cần tìm một ít không gian và có lẽ ít tốn kém nhất là chỉ cần đặt màu đường viền ô thành màu nền của bảng sau đó đặt độ rộng đường viền để có kết quả mong muốn!

    cell.layer.borderColor = blueColor.CGColor
    cell.layer.borderWidth = 3

1
Không phải là một ý tưởng tốt cho nền trong suốt. Nếu không, nó có thể làm việc.
ergunkocak

1
Đây là sự thật. Không phải là một giải pháp cho tất cả các trường hợp nhưng nó sẽ làm việc cho một số! @ergunkocak
Craig

8

Nếu bạn chưa sử dụng tiêu đề phần (hoặc chân trang), bạn có thể sử dụng chúng để thêm khoảng cách tùy ý vào các ô của bảng. Thay vì có một phần với n hàng, hãy tạo một bảng có n phần với mỗi hàng một hàng.

Thực hiện tableView:heightForHeaderInSection:phương pháp để kiểm soát khoảng cách.

Bạn cũng có thể muốn thực hiện tableView:viewForHeaderInSection:để kiểm soát khoảng cách trông như thế nào.


8

Tôi đã giải quyết nó như thế này trong Swift 4.

Tôi tạo một phần mở rộng của UITableViewCell và bao gồm mã này:

override open var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        var frame =  newFrame
        frame.origin.y += 10
        frame.origin.x += 10
        frame.size.height -= 15
        frame.size.width -= 2 * 10
        super.frame = frame
    }
}

override open func awakeFromNib() {
    super.awakeFromNib()
    layer.cornerRadius = 15
    layer.masksToBounds = false
}

Tôi hy vọng nó sẽ giúp bạn.


văn bản trong ô bị cắt.
Mehdico

ghi đè CGRect đang hoạt động và tôi đã không thêm awakeFromNib.
Eric Tan

5

Ví dụ trong swift 3 ..

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

  1. Tạo một ứng dụng xem đơn
  2. thêm bảng xem trong bộ điều khiển xem
  3. thêm một customcell cho ô tablview
  4. xem mã điều khiển dưới đây như

       class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
       @IBOutlet weak var tableView: UITableView!
    
    
        var arraytable = [[String:Any]]()
         override func viewDidLoad() {
         super.viewDidLoad()
    
         arraytable = [
         ["title":"About Us","detail":"RA-InfoTech Ltd -A Joint Venture IT Company formed by Bank Asia Ltd"],
         ["title":"Contact","detail":"Bengal Center (4th & 6th Floor), 28, Topkhana Road, Dhaka - 1000, Bangladesh"]
    ]
    
    
    
    
    
    
       tableView.delegate = self
       tableView.dataSource = self
    
       //For Auto Resize Table View Cell;
      tableView.estimatedRowHeight = 44
       tableView.rowHeight = UITableViewAutomaticDimension
    
       //Detault Background clear
       tableView.backgroundColor = UIColor.clear
    }

    func numberOfSections (trong bảngView: UITableView) -> Int {return Arraytable.count}

       func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return 1
     }
    
    // Set the spacing between sections
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 10
    }
    
    // Make the background color show through
      func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView()
    headerView.backgroundColor = UIColor.clear
    
    return headerView
    }
    
         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as! CustomCell
    
         cell.tv_title.text = arraytable[indexPath.section]["title"] as! String?
        cell.tv_details.text = arraytable[indexPath.section]["detail"] as! String?
    
       //label height dynamically increase
       cell.tv_details.numberOfLines = 0
    
    
    
    
       //For bottom border to tv_title;
       let frame =  cell.tv_title.frame
        let bottomLayer = CALayer()
       bottomLayer.frame = CGRect(x: 0, y: frame.height - 1, width: frame.width, height: 1)
        bottomLayer.backgroundColor = UIColor.black.cgColor
       cell.tv_title.layer.addSublayer(bottomLayer)
    
      //borderColor,borderWidth, cornerRadius
      cell.backgroundColor = UIColor.lightGray
      cell.layer.borderColor = UIColor.red.cgColor
      cell.layer.borderWidth = 1
      cell.layer.cornerRadius = 8
      cell.clipsToBounds = true
    
      return cell
      }
    
       }
  5. Tải nguồn đầy đủ về Github: link

    https://github.com/enamul95/CustomSectionTable


nó đã sao chép một câu trả lời khác mà @Suragch đã được trả lời trước cho phiên bản nhanh, xin vui lòng tránh tạo bản sao
Amr Angry

1
đây không phải là một giải pháp tốt Nếu bạn cần phần tiêu đề với tiêu đề thì điều này sẽ không hoạt động
kuzdu

4

Ba cách tiếp cận tôi có thể nghĩ ra:

  1. Tạo một ô bảng tùy chỉnh đặt chế độ xem của toàn bộ ô theo cách bạn muốn

  2. Thay vì thêm hình ảnh vào chế độ xem hình ảnh, hãy xóa các khung nhìn của chế độ xem hình ảnh, tạo chế độ xem tùy chỉnh thêm UIImageView cho hình ảnh và chế độ xem khác, có lẽ là một UIView đơn giản cung cấp khoảng cách mong muốn và thêm nó dưới dạng một khung nhìn phụ xem hình ảnh.

  3. Tôi muốn đề nghị bạn thao tác trực tiếp với UIImageView để đặt kích thước / phần đệm cố định, nhưng tôi không ở gần Xcode nên tôi không thể xác nhận liệu nó có hoạt động hay không.

Điều đó có ý nghĩa?


4

Có, bạn có thể tăng hoặc giảm khoảng cách (phần đệm) giữa hai ô bằng cách tạo một chế độ xem cơ sở trên chế độ xem nội dung trong ô. Hãy xóa màu cho nền xem nội dung và bạn có thể điều chỉnh chiều cao của chế độ xem cơ sở để tạo khoảng cách giữa các ô.


4

Dựa trên câu trả lời của Husam: Sử dụng lớp ô thay vì chế độ xem nội dung cho phép thêm đường viền xung quanh toàn bộ ô và phụ kiện nếu cần. Phương pháp này yêu cầu điều chỉnh cẩn thận các ràng buộc dưới cùng của ô cũng như các phần tử chèn nếu không chế độ xem sẽ không phù hợp.

@implementation TableViewCell

- (void)awakeFromNib { 
    ... 
}

- (void) layoutSubviews {
    [super layoutSubviews];

    CGRect newFrame = UIEdgeInsetsInsetRect(self.layer.frame, UIEdgeInsetsMake(4, 0, 4, 0));
    self.layer.frame = newFrame;
}

@end

3

Thay đổi số lượng hàng trong phần thành 1 Bạn đã thay đổi số phần thay vì số lượng hàng

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        1
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

Ở đây bạn đặt khoảng cách giữa các hàng

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }

2

Tôi nghĩ rằng đây là giải pháp sạch nhất:

class MyTableViewCell: UITableViewCell {
    override func awakeFromNib() {
        super.awakeFromNib()
        layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
    }
}

1
Tôi không thể thấy bất kỳ thay đổi trực quan nào sau khi áp dụng layoutMarginscách này. Có lẽ bởi vì tôi đang sử dụng autolayout.
Cœur

Các lề sẽ không "phá vỡ" một chiều cao rõ ràng cho ô, vì vậy bạn cần phải có chiều cao tự động để các ô này hoạt động
Aviel Gross

1
Tôi có chiều cao tự động.
Cœur

2

Bài viết này đã giúp, đó là khá nhiều những gì các câu trả lời khác nói nhưng tóm tắt và súc tích

https://medium.com/@andersongusmao/left-and-right-margins-on-uitableviewcell-595f0ba5f5e6

Trong đó, anh ta chỉ áp dụng chúng cho bên trái và bên phải nhưng UIEdgeInsetsMakeinit cho phép thêm phần đệm vào tất cả bốn điểm.

func UIEdgeInsetsMake (_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> UIEdgeInsets

Mô tả
Tạo một hình nhỏ cạnh cho một nút hoặc chế độ xem. Một hình nhỏ là một lề xung quanh một hình chữ nhật. Các giá trị dương biểu thị các lề gần với trung tâm của hình chữ nhật, trong khi các giá trị âm biểu thị các lề xa hơn từ tâm.

Thông số
đầu: Hình nhỏ ở phía trên của một đối tượng.
left: Hình nhỏ bên trái của một đối tượng
dưới cùng: Hình nhỏ bên dưới của một đối tượng.
bên phải: Hình nhỏ bên phải của một đối tượng.

Trả về
Một hình nhỏ cho nút hoặc dạng xem

Lưu ý rằng UIEdgeInsets cũng có thể được sử dụng để đạt được điều tương tự.

Xcode 9.3 / Swift 4


Câu trả lời này không chính xác nói mã tương thích với Swift 4, nhưng UIEdgeInsetsMake đã không được chấp nhận. Thay vào đó nên sử dụng UIEdgeInsets.
Jose

developer.apple.com/documentation/uikit/ trên chính xác nơi mà nó nói nó đã bị phản đối? Tôi sử dụng điều này trong các dự án của mình và tôi đang làm việc với Xcode mới nhất, do đó Swift 9.3 @ José
Mauricio Chirino

Bạn nói đúng, xin lỗi, xấu của tôi. UIEdgeInsets được ưa thích, nhưng điều đó không có nghĩa là cái khác không được dùng nữa. SwiftLint sẽ phàn nàn về nhà xây dựng kế thừa mặc dù khi sử dụng UIEdgeInsetsMake.
Jose

1
OK đã nhận nó. Vui lòng xóa downvote nếu bạn là người đã chọn, tôi không bao giờ nói câu trả lời của tôi là duy nhất có thể.
Mauricio Chirino

Nó nói rằng tôi không thể thay đổi phiếu bầu của mình trừ khi bạn thay đổi câu trả lời. Bạn có thể chỉnh từ ngữ một chút không?
Jose

2

Sử dụng một loạt các phần khác nhau là không cần thiết. Các câu trả lời khác sử dụng phần trong khung và CGRect và các lớp và ... BLAH. Không tốt; sử dụng bố cục tự động và UITableViewCell tùy chỉnh. Trong UITableViewCell đó, thay vì xem phụ nội dung của bạn bên trong contentView, hãy tạo một containerView mới (UIView), xem chế độ xem container bên trong contentView, sau đó xem tất cả các chế độ xem của bạn trong chế độ xem container.

Để tạo khoảng cách ngay bây giờ, chỉ cần chỉnh sửa lề bố cục của chế độ xem vùng chứa, như sau:

class CustomTableViewCell: UITableViewCell {
    let containerView = UIView()
    let imageView = UIImageView()

    required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)}

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        containerView.translatesAutoResizingMaskIntoConstraints = false
        imageView.translatesAutoResizingMaskIntoConstraints = false
        contentView.addSubview(containerView)
        containerView.addSubview(imageView)

        contentView.layoutMargins = UIEdgeInsets(top: 15, left: 3, bottom: 15, right: 3)
        containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17) // It isn't really necessary unless you've got an extremely complex table view cell. Otherwise, you could just write e.g. containerView.topAnchor

        let cg = contentView.layoutMarginsGuide
        let lg = containerView.layoutMarginsGuide
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: cg.topAnchor),
            containerView.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
            imageView.topAnchor.constraint(equalTo: lg.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
        ])
    }
}


1

Tình huống của tôi là tôi đã sử dụng UIView tùy chỉnh để xemForHeader trong phần cũng heightForHeader trong phần trả về chiều cao không đổi nói 40, vấn đề là khi không có dữ liệu tất cả các chế độ xem tiêu đề được chạm vào nhau. Vì vậy, tôi muốn khoảng trống giữa phần không có dữ liệu nên tôi đã sửa bằng cách thay đổi mặt phẳng "kiểu xem bảng" thành "Nhóm". Và nó hoạt động với tôi.


1

Kiểm tra giải pháp của tôi trên GitHub với phân lớp UITableViewvà sử dụng các tính năng thời gian chạy của Objective-C.
Về cơ bản, nó sử dụng cấu trúc dữ liệu riêng tư của Apple UITableViewRowDatamà tôi đã tìm kiếm tiêu đề thời gian chạy riêng tư của UITableView:

https://github.com/JaviSoto/iOS10-R.78-Headers/blob/master/Frameworks/UIKit.framework/UITableView.h ,

và đây là lớp riêng mong muốn chứa mọi thứ bạn cần để bố trí các khoảng cách của các ô theo cách bạn muốn mà không cần đặt nó trong các lớp của ô:

https://github.com/JaviSoto/iOS10-R.78-Headers/blob/master/Frameworks/UIKit.framework/UITableViewRowData.h


1

Tôi đã gặp khó khăn khi điều này hoạt động cùng với màu nền và chế độ xem phụ kiện trong ô. Cuối cùng phải:

1) Đặt thuộc tính chế độ xem nền của ô với bộ UIView có màu nền.

let view = UIView()
view.backgroundColor = UIColor.white
self.backgroundView = view

2) Định vị lại chế độ xem này trong layoutSubview để thêm ý tưởng về khoảng cách

override func layoutSubviews() {
    super.layoutSubviews()
    backgroundView?.frame = backgroundView?.frame.inset(by: UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 0)) ?? CGRect.zero
}

1

Sử dụng các tiêu đề làm khoảng cách sẽ hoạt động tốt Tôi đoán nếu bạn không muốn sử dụng bất kỳ tiêu đề nào. Nếu không, có lẽ không phải là ý tưởng tốt nhất. Những gì tôi nghĩ là tạo ra một khung nhìn ô tùy chỉnh.

Ví dụ:

Trong ô tùy chỉnh, tạo chế độ xem nền với các ràng buộc để nó không lấp đầy toàn bộ ô, cung cấp cho nó một số phần đệm.

Sau đó, làm cho nền bảng xem ẩn và loại bỏ các dấu phân cách:

// Make the background invisible
tableView.backgroundView = UIView()
tableView.backgroundColor = .clear

// Remove the separators
tableview.separatorStyle = .none

1

Nếu bạn không muốn thay đổi phần và số hàng của chế độ xem bảng của mình (như tôi đã làm), thì đây là những gì bạn làm:

1) Thêm ImageView vào cuối chế độ xem ô của bảng.

2) Làm cho nó cùng màu với màu nền của chế độ xem bảng.

Tôi đã thực hiện điều này trong ứng dụng của mình và nó hoạt động hoàn hảo. Chúc mừng! : D


0

nhập mô tả hình ảnh ở đâySWift-5, Khoảng cách giữa UITableViewCell

    1. use sections instead of rows
    2. each section should return one row
    3. assign your cell data like this e.g [indexPath.section], instead of row
    4. use UITableView Method "heightForHeader" and return your desired spacing
    5. Do rest things as you were doing it

    Thanks!

0

Bạn chỉ có thể sử dụng ràng buộc trong mã như thế này:

class viewCell : UITableViewCell 
{

@IBOutlet weak var container: UIView!



func setShape() {
    self.container.backgroundColor = .blue
    self.container.layer.cornerRadius = 20
    container.translatesAutoresizingMaskIntoConstraints = false
    self.container.widthAnchor.constraint(equalTo:contentView.widthAnchor , constant: -40).isActive = true
           self.container.heightAnchor.constraint(equalTo: contentView.heightAnchor,constant: -20).isActive = true
           self.container.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
           self.container.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true

    }
}

điều quan trọng là thêm subview (container) và đặt các yếu tố khác vào đó.


-1

Giải pháp Swift 5.0

Bên trong lớp con UITableViewCell

override func layoutSubviews() {
    super.layoutSubviews()
    let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    bounds = UIEdgeInsetsInsetRect(bounds, padding)
}


-4

Sử dụng UITableViewDelegate heightForRowAtIndexPathvà trả về chiều cao của hàng.

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 return 100.0f ;
}

Câu hỏi là làm thế nào để thêm khoảng cách giữa các ô chứ không phải chiều cao của ô
shippo7
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.