Swift - Наследование UIViewController от базового базового класса, который также является UIViewController - PullRequest
0 голосов
/ 10 ноября 2018

Итак, у меня есть базовый класс DataViewController<T>, который наследуется от UITableViewController следующим образом:

class DataTableViewController<T : BMPage<BMData>> : UITableViewController, UISearchBarDelegate {
    // implementations...
}

У меня также есть TournamentsViewController, который наследуется от DataViewController с переданными обобщениями:

class TournamentsViewController: DataTableViewController<TournamentPage> {
    // overrides, etc.
}

Для справки: BMPage<T>:

open class BMPage<T : Codable> : Decodable {

    public enum CodingKeys: String, CodingKey {
        case data
    }

    var data : [T]

    required public init(from decoder:Decoder) throws {
        let vals = try decoder.container(keyedBy: CodingKeys.self)
        data = try vals.decode([T].self, forKey: .data)
    }
}

extension BMPage: Encodable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(data, forKey: .data)
    }
}

... и BMData:

open class BMData : Codable {

    public enum CodingKeys: CodingKey {
        case id
        case name
    }

    var id: Int
    var name: String

    required public init(from decoder:Decoder) throws {
        let vals = try decoder.container(keyedBy: CodingKeys.self)
        id = try vals.decode(Int.self, forKey: .id)
        name = try vals.decode(String.self, forKey: .name)
    }
}

То, чего я пытаюсь достичь: различные UITableViewController подклассы, которым просто нужно указать универсальные шаблоны, чтобы указать их конкретные данные. Вот мои реализации Tournament и TournamentPage, которые должны лучше объяснить эту концепцию:

open class Tournament : BMData {
    let game_id: Int = 0
    let game_iteration_id: Int = 0
    let state: Int = 0
    let starts_at: String = ""
    let creator_id: Int = 0
    let stream_url: String? = nil
    let entrant_count: Int = 0
    let prereg_count: Int = 0
    let path: String = ""
}

open class TournamentPage : BMPage<BMData> {
    public enum CodingKeys: String, CodingKey {
        case data = "tournaments"
    }

    let page: String? = nil
    let results_per_page: String = ""
    let tournament_count: Int = 0
}

Проблема: компилятору не нравится, что я делаю это, поскольку он выдает несколько, но очень похожие ошибки, такие как:

  • Cannot convert return expression of type 'TournamentsViewController' to return type 'UIViewController'
  • Cannot convert return expression of type 'TournamentsViewController?' to return type 'UIViewController?'

Вот пример такого выражения (взято из значения по умолчанию ModelController, которое XCode добавил туда, где все эти ошибки происходят:

    let dataViewController = storyboard.instantiateViewController(withIdentifier: "DataViewController") as! TournamentsViewController

Есть ли способ достичь того, что я пытаюсь сделать? Признаюсь, я новичок в Swift (только начал изучать его на этой неделе), так что, возможно, я совершенно не понимаю типичные практики Swift и просто то, для чего он предназначен, но достигаю этого на языке, таком как C # (и, возможно, даже Objective-C, хотя я немного заржавел, так как я давно его использовал), это почти то, что я делаю здесь.

1 Ответ

0 голосов
/ 10 ноября 2018

Вы пытались создать такой экземпляр контроллера вида?
let viewController = MyTableViewController() Чем navigationController.pushViewController(viewController, animated: true) }

...