【问题标题】:How to setup multiple views for one controller如何为一个控制器设置多个视图
【发布时间】:2016-01-26 20:03:28
【问题描述】:

我正在制作一个篮筐战术应用程序。用户可以在多种战术之间进行选择,并为每个战术球员命名。

我有超过 30 种战术。每种战术之间唯一不同的是球员在地面上的位置(x 和 y)。一个策略只是一个带有背景图像的视图和每个玩家的 UIViews。 我想知道使用同一控制器管理每种策略(视图)的最佳方法是什么。

【问题讨论】:

  • 是用户选择呈现的战术视图吗?还是你想一次展示所有 30 种战术?
  • 创建 UIView 的自定义类并创建其多个对象并将它们作为子视图添加到 viewController 的 self.view 中,
  • 是的,该策略由用户选择呈现。然后用户可以点击玩家并为其命名@Mr.T

标签: ios swift


【解决方案1】:

我会通过为您的战术视图创建一个子类以编程方式创建它们,该子类可用于显示您所有不同的球员位置。

我还建议您为播放器视图创建一个子类,因为除了标签文本和位置之外,它们似乎是相同的。所以首先,你应该创建一个PlayerView 子类:

class PlayerView : UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)

        // do custom setup for the player view (add label etc)

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

}

然后你想为TacticView 创建一个子类。您希望如何存储每个玩家视图的位置完全取决于您,但在此示例中,我使用 2D 快速数组来表示它们。您可能希望将它们转换为更易于管理的格式(例如 .plist 文件)。

您可能还想根据屏幕大小定义它们,以节省使用约束。比如CGPoint(x: 0.3, y: 0.5)(那么设置位置的时候只需要乘以屏幕大小)。

class TacticView : UIView {

    let playerViewPositions : [[CGPoint]] = [ // store all your positions in a 2D array
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)], // tactic 0
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)], // tactic 1
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)], // etc
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
        [CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20), CGPoint(x: 10, y: 20)],
    ]

    var tacticIndex:Int = 0 {
        didSet { // reload views when the index value changes
            self.reloadViews()
        }
    }

    var playerArray = NSArray()

    convenience init(frame:CGRect, tacticIndex:Int) {
        self.init(frame: frame)
        self.tacticIndex = tacticIndex
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        // do further setup (add background etc)

        let arr = NSMutableArray()
        for _ in 0..<6 {
            let playerView = PlayerView(frame: CGRect(origin: CGPointZero, size: CGSize(width:20, height:10)))
            arr.addObject(playerView)
            addSubview(playerView)
        }

        playerArray = arr.copy() as! NSArray

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func reloadViews() {
        for i in 0..<playerArray.count {
            let p = playerArray[i] as! PlayerView
            p.center = playerViewPositions[tacticIndex][i]
        }
    }

}

该子类包含您的玩家视图数组(视图本身可以跨战术重复使用,但如果您不想重复使用它们可以初始化多个战术视图)。

它还允许您通过tacticIndex 属性在策略之间进行更改,这会将视图的定位更改为给定的策略索引。

最后,您要初始化并将其添加到您的主视图控制器:

class ViewController: UIViewController {

    let tactic = TacticView(frame: UIScreen.mainScreen().bounds, tacticIndex:0)

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(tactic)

    }

    func changeTacticIndex(index:Int) {
        tactic.tacticIndex = index
    }

}

【讨论】:

  • 仓位逻辑呢?我用界面生成器来做我的视图。定义视图位置及其约束的最佳方式是什么?
  • 我已经澄清了我的答案
【解决方案2】:

很多可能性来实现您的目标。一种是:

1- 为您的策略选择一种持久性方法,因为您需要一个地方来存储和/或检索数据。您可以通过任何 iOS 持久源(CoreData、plist、从 JSON 获取等)来管理播放器视图的位置,这取决于您打算对最终应用执行什么操作。

2 - 在您的视图控制器上,您可以在 NSArray 或 NSDictionary 上一次加载所有 30 种策略(再次取决于您希望实现的目标)。

3 - 在 tableView、CollectionView 或用户可以在特定上选择的任何 UI 上表示策略。

4 - 向用户展示战术,我认为最好的方法是通过 CoreAnimation 在用户选择不同的战术时改变 playerViews 的位置。 http://www.raywenderlich.com有很好的动画教程。

希望能帮助您找到最佳解决方案。

【讨论】:

    猜你喜欢
    • 2015-02-19
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多