Reputation: 5038
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
Upvotes: 0
Views: 2320
Reputation: 3093
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.
Upvotes: 2