Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
168 views
in Technique[技术] by (71.8m points)

ios - swift UITableViewCell with protocol issue

I have a protocol

protocol AttibuteValueCellProtocol {
    func set(attribute: String, value: String)
}

And in my tableView's datasource method I want my cell to confirm to this protocol. In objective-c I could do that, but in SWIFT it gives the error when I try to use as? UITableViewCell<AttibuteValueCellProtocol>. In objective-C it always worked if I do ((UITableViewCell<AttibuteValueCellProtocol> *)cell)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? UITableViewCell<AttibuteValueCellProtocol>
}

What can I replace it with?

P.S. Error looks like this http://take.ms/OHRA3

I don't need extension , because when I deque cell , it will be CustomCell (and CustomCell conforms to Protocol), but this class can use different cell identifiers so this class shouldn't know about the cell class name and not every cell conforms to AttibuteValueCellProtocol , this class has to know that we have cell that conforms to protocol AttibuteValueCellProtocol

I Objective-C I can do that and it will compile (I understand that it will not work because view1 doesn't conform to protocol, but it's easy to create proper view and it will work,here I just give an example) :

#import "TestViewController.h"

@interface TestViewController ()

@end

@protocol TestProtocol <NSObject>

- (void)testMethod;

@end

@implementation TestViewController

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

    UIView *view1 = [[UIView alloc] init];
    UIView *viewForProtocolJustToShow = (UIView<TestProtocol> *)view1;
}

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


@end
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Problem

As the error says, UITableViewCell is not a generic type. With this syntax you are confusing conforming to a protocol with setting the type of a generic object.

Solution 1: Extensions

To get a UITableViewCell that conforms to the AttibuteValueCellProtocol, you can use an extension:

extension UITableViewCell: AttibuteValueCellProtocol {
  // implementation of AttibuteValueCellProtocol requirements goes here
}

You will have to implement the AttibuteValueCellProtocol methods as Swift (and Objective-C) have no way of knowing how they should be defined.

Solution 2: Subclass

Extending the whole UITableViewCell class could create some strange side effects if you do not always want those extra methods. You can also just subclass UITableViewCell and implement the AttibuteValueCellProtocol protocol there:

class MyTableViewCell: UITableViewCell, AttibuteValueCellProtocol {
  // implementation of AttibuteValueCellProtocol requirements goes here
}

And then, you can do:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? MyTableViewCell
}

Solution 3: Protocol

You can also just check if the returned UITableViewCell conforms to a specific protocol:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? MyProtocol
}

Note that this will set cell to nil if it does not conform.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...