通过UITableVIew

时间:2019-05-22 19:51:35

标签: ios swift uitableview uisearchbar uisearchcontroller

我已基于此tutorial设计了搜索组件。

在表格视图中只有一个部分的情况下,它很好用,所以我不必担心嵌套的东西。

这是我的代码:

import UIKit

protocol Searchable {
    var query: String { get }
    var isSelected: Bool { get set }
}

class BaseSearchDataSource<V, T: Searchable>: NSObject, UITableViewDataSource where V: BaseTableViewCell<T> {

    private var models: [T]
    private let configureCell: CellConfiguration
    typealias CellConfiguration = (V, T) -> V
    private var searchResults: [T] = []
    private var isSearchActive: Bool = false

    init(models: [T], configureCell: @escaping CellConfiguration) {
        self.models = models
        self.configureCell = configureCell
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return isSearchActive ? searchResults.count : models.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: V = tableView.dequeueReusableCell(forIndexPath: indexPath)
        let model = getModelAt(indexPath)
        return configureCell(cell, model)
    }

    func getModelAt(_ indexPath: IndexPath) -> T {
        return isSearchActive ? searchResults[indexPath.item] : models[indexPath.item]
    }

    func search(query: String) {
        isSearchActive = !query.isEmpty
        searchResults = models.filter {
            let queryToFind = $0.query.range(of: query, options: NSString.CompareOptions.caseInsensitive)
            return (queryToFind != nil)
        }
    }
}

我有一个符合指定协议的此类实现:

class MuscleSelectableItem: Searchable {

var query: String {
    return name
}

var isSelected: Bool

let name: String
let muscle: MusclEntity

init (isSelected: Bool, name: String, muscle: MusclEntity) {
    self.isSelected = isSelected
    self.name = name
    self.muscle = muscle
}
}

因此,现在当我使用父级BaseSearchDataSource的子类时,我可以简单地指定一个要加载到表视图中的类,并使该类可搜索。所以现在我的var models: [T]将模型表示为[MuscleSelectableItem]

我了解到我需要使用一些带有嵌套项的section对象:

class TableViewSection {
var items: [MuscleSelectableItem]
}

但是上面代码的问题是我为[MuscleSelectableItem]指定了具体类型items

如何用[T]声明TableViewSectionitems,直到我们在子类中告诉编译器我们要为items使用哪种类型(例如搜索)之前,如何声明items适用于城市,肌肉或书籍或其他任何实体,因此IDEAL MODEL small STACK 100h DATASEG filename db 'lv1maze.bmp',0 filename2 db 'Dotmaze.bmp',0 filehandle dw ? Header db 54 dup (0) Palette db 256*4 dup (0) ScrLine db 320 dup (0) ErrorMsg db 'Error', 13, 10,'$' color db 12 CODESEG proc OpenFile ; Open file mov ah, 3Dh xor al, al mov dx, offset filename int 21h jc openerror mov [filehandle], ax ret openerror: mov dx, offset ErrorMsg mov ah, 9h int 21h ret endp OpenFile ; dot pic proc Opendot ;dot pic mov ah, 3Dh xor al, al mov dx, offset filename2 int 21h jc openerror mov [filehandle], ax ret endp Opendot proc ReadHeader ; Read BMP file header, 54 bytes mov ah,3fh mov bx, [filehandle] mov cx,54 mov dx,offset Header int 21h ret endp ReadHeader proc ReadPalette ; Read BMP file color palette, 256 colors * 4 bytes (400h) mov ah,3fh mov cx,400h mov dx,offset Palette int 21h ret endp ReadPalette proc CopyPal ; Copy the colors palette to the video memory ; The number of the first color should be sent to port 3C8h ; The palette is sent to port 3C9h mov si,offset Palette mov cx,256 mov dx,3C8h mov al,0 ; Copy starting color to port 3C8h out dx,al ; Copy palette itself to port 3C9h inc dx PalLoop: ; Note: Colors in a BMP file are saved as BGR values rather than RGB. mov al,[si+2] ; Get red value. shr al,2 ; Max. is 255, but video palette maximal ; value is 63. Therefore dividing by 4. out dx,al ; Send it. mov al,[si+1] ; Get green value. shr al,2 out dx,al ; Send it. mov al,[si] ; Get blue value. shr al,2 out dx,al ; Send it. add si,4 ; Point to next color. ; (There is a null chr. after every color.) loop PalLoop ret endp CopyPal proc CopyBitmap ; BMP graphics are saved upside-down. ; Read the graphic line by line (200 lines in VGA format), ; displaying the lines from bottom to top. mov ax, 0A000h mov es, ax mov cx,200 PrintBMPLoop: push cx ; di = cx*320, point to the correct screen line mov di,cx shl cx,6 shl di,8 add di,cx ; Read one line mov ah,3fh mov cx,320 mov dx,offset ScrLine int 21h ; Copy one line into video memory cld ; Clear direction flag, for movsb mov cx,320 mov si,offset ScrLine rep movsb ; Copy line to the screen ;rep movsb is same as the following code: ;mov es:di, ds:si ;inc si ;inc di ;dec cx ;loop until cx=0 pop cx loop PrintBMPLoop ret endp CopyBitmap start: mov ax,@data mov ds,ax ; Graphics mode mov ax,13h int 10h call OpenFile call ReadHeader call ReadPalette call CopyPal call CopyBitmap ; Initializes the mouse mov ax,0h int 33h ; showing the mouse mov ax,1h int 33h ; Loop until mouse click MouseLP: mov ax,3h int 33h cmp bx, 01h ; check left mouse click jne MouseLP ; Print dot near mouse location shr cx,1 ; adjust cx to range 0-319, to fit screen sub dx, 1 ; move one pixel, so the pixel will not be hidden by mouse mov bh,0h mov al,[color] mov ah,0Ch int 10h ; Press any key to continue mov ah,00h int 16h ; Text mode mov ax,3h int 10h exit: mov ax,4C00h int 21h END start 可以是其中的任何一个

我也不希望我的协议包含搜索和选择功能,如何正确地将其分开?

1 个答案:

答案 0 :(得分:0)

您也可以在包装中使用泛型。在上述情况下,它看起来像这样:

class TableViewSection<T> {
    var items = [T]()

}

您还可以构建一个TableDataSource类,该类具有一组表视图节,这将打开诸如基于indexPath下标的机会,然后使其符合收集协议,从而获得过滤器,计数等功能。

  

我也不希望我的协议包含搜索和选择功能,如何正确地将其分开?

Swift允许使用类型别名来组成较小协议的协议。上面可以这样划分:

protocol Searchable {
    var query: String { get }
}

protocol Selectable {
    var isSelected: Bool { get set }
}

typealias SearchAndSelectable = Searchable & Selectable

SearchAndSelectable类型的变量上将同时具有'query'和'isSelected'值,这对于可以利用这两种协议类型的通用约束或函数很方便。