私はユーザR menke他の助けを借りて実現しました。 私の目標はUISearchBarDelegate、UITableViewDelegateと正しくJSONを解析することができるように型クラスを必要とする私のgetDataメソッドを(扱うことができるGenericListProtocolを持つことです。
import Foundation
import UIKit
protocol GenericListProtocol : UISearchBarDelegate, UITableViewDelegate{
typealias T : MyModel // MyModel is a model i use for getId, getDate...
var list : [T] { get set }
var filteredlist : [T] { get set }
var searchActive : Bool { get set }
func setData(tableView : UITableView, myList : [T])
func setData()
func getData(tableView : UITableView, objectType : T, var myList : [T])
func filterContentForSearchText(searchText: String)
}
extension GenericListProtocol {
func setData(atableView : UITableView, myList : [T]) {
print("reloading tableView data")
atableView.reloadData()
}
func getData(tableView : UITableView, objectType : T, var myList : [T]) {
let dao: GenericDao<T> = GenericDao<T>()
let view : UIView = UIView()
let c: CallListListener<T> = CallListListener<T>(view: view, loadingLabel: "loading", save: true, name: "ProductModel")
c.onSuccess = { (onSuccess: JsonMessageList<T>) in
print("status " + onSuccess._meta!.status!) // this is from my ws
myList = onSuccess.records
self.setData(tableView, myList: myList)
}
c.onFinally = { (any: AnyObject) in
// tableView.stopPullToRefresh()
}
// my dao saves json list on NSUSER, so we check if its already downloaded
let savedList = c.getDefaultList()
if (savedList == nil) {
dao.getAll(c);
}
else {
myList = savedList!
print(String(myList.count))
self.setData(tableView, myList: myList)
}
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
print("searching")
self.filterContentForSearchText(searchText)
if(filteredlist.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.setData()
}
}
私が最もUISearchBarDelegate、UITableViewDelegateのメソッドを実装することができましたが、
import Foundation
import UIKit
import EVReflection
import AlamofireJsonToObjects
class ProductListController : GenericListController, GenericListProtocol {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var list : [ProductModel] = [ProductModel]()
var filteredlist : [ProductModel] = [ProductModel]()
var searchActive : Bool = false
override func setInit() {
self.searchBar.delegate = self
self.listName = "ProductModel"
self.setTableViewStyle(self.tableView, searchBar4 : self.searchBar)
getData(self.tableView, objectType: ProductModel(), myList: self.list)
}
// this method hasnt worked from extension, so i just pasted it here
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
self.filterContentForSearchText(searchText)
if(filteredlist.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.setData(self.tableView, myList: list)
}
// this method hasnt worked from extension, so i just pasted it here
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchActive {
return self.filteredlist.count
} else {
return self.list.count
}
}
// self.list = myList hasnt worked from extension, so i just pasted it here
func setData(atableView: UITableView, myList : [ProductModel]) {
print(String(myList.count))
self.list = myList
print(String(self.list.count))
self.tableView.reloadData()
}
// i decided to implement this method because of the tableView
func setData() {
self.tableView.reloadData()
}
// this method hasnt worked from extension, so i just pasted it here
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:GenericListCell = tableView.dequeueReusableCellWithIdentifier("cell") as! GenericListCell
var object : ProductModel
if searchActive {
object = filteredlist[indexPath.row]
} else {
object = list[indexPath.row]
}
cell.formatData(object.name!, subtitle: object.price ?? "valor", char: object.name!)
print("returning cell")
return cell
}
override func viewDidLoad() {
// searchFuckinBar.delegate = self
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func filterContentForSearchText(searchText: String) {
// Filter the array using the filter method
self.filteredlist = self.list.filter({(object: ProductModel) -> Bool in
// let categoryMatch = (scope == "All") || (object.category == scope)
let stringMatch = object.name!.lowercaseString.rangeOfString(searchText.lowercaseString)
return (stringMatch != nil)
})
}
func formatCell(cell : GenericListCell, object : ProductModel) {
cell.formatData(object.name!, subtitle: object.price ?? "valor", char: object.name!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
は* GenericListControllerは、@ R-MENKEはabovを述べたように
なぜあなたはのUIViewControllerで、一般的なモデルを追加する必要がありますか? –
リスト・コントローラのロジックは常に同じなので、オブジェクトのタイプを変更するだけです。私はproductList、saleList、userListを持ち、それらはすべて同じメソッドとロジックを共有しています。 DetailsController、AddControllerと同じです。ジェネリックスを使用できない場合は、私が作成した新しいコントローラにgetData関数をコピーして貼り付ける必要があります(その内部に型が必要なDAOメソッドがあります)。 – sagits
@sagitsジェネリック型(この場合はProductModel)の属性にアクセスすることができないので、これがどれほど有用なのか不思議でした。あなたの方法ではなく、私のものではありませんか?すべてのTが準拠する基本クラスも作成していますか? –