前提・実現したいこと
view
全体にグリッド線を描画したい。
UIView
のサブクラス(下記ソースのCanvasView
)で、そのビュー全体にグリッド線を描画するために、 UIView
のdraw(_ rect: CGRect)
をオーバーライドし、UIBezierPath
を使用してグリッド線を描画しているのですが、ビューの大きさが大きくなると、グリッドが表示されません。
draw(_ rect: CGRect)
は呼ばれているのですが、エラーも出力されておらず、原因がわかりません。
また、init(frame: CGRect)
でbackgroundColor
の設定も行なっていますが、こちらも反映されなくなります。
下記ソースではボタンでスクロールビューに載せるキャンバスを切り替えていますが、
小さいキャンバンスはグリッド線が描画されますが、
大きいキャンバスはグリッド線が描画されません。
原因および対策方法をご教授ください。
クラスの説明
ViewController
:スクロールビュー上にキャンバスを表示する
CanvasView
:グリッドを描画するUIView
のサブクラス
Grid
:グリッドを描画するために、グリッドの各マス目の四隅のポイントを保持する
グリッドの描画処理
CanvasView
におけるグリッドの描画処理の順番です。
init(frame: CGRect)
を呼ぶbackgroundColor
に.yellow
を設定するinitGrid()
にてビュー全体におさまるだけのGrid
の配列を作成しgrids
に設定するdraw(_ rect: CGRect)
にて、grids
のすべての要素について、UIBezeriPathを使用して各ポイントを線でつなぎ、グリッド線とする
Swift
1class ViewController: UIViewController { 2 // キャンバス 3 var canvasView: CanvasView! 4 // キャンバスを載せるスクロールビュー 5 @IBOutlet weak var scrollView: UIScrollView! 6 7 // 小さいキャンバスを表示する 8 @IBAction func small(_ sender: UIButton) { 9 canvasView.removeFromSuperview() 10 11 canvasView = CanvasView(frame: scrollView.bounds) 12 13 scrollView.addSubview(canvasView) 14 scrollView.contentSize = canvasView.frame.size 15 scrollView.contentOffset = CGPoint(x: 0, y: 0) 16 } 17 // 大きいキャンバスを表示する 18 @IBAction func big(_ sender: UIButton) { 19 canvasView.removeFromSuperview() 20 21 canvasView = CanvasView(frame: CGRect(x: 0, y: 0, width: 6000, height: 4000)) 22 23 scrollView.addSubview(canvasView) 24 scrollView.contentSize = canvasView.frame.size 25 scrollView.contentOffset = CGPoint(x: 0, y: 0) 26 } 27 override func viewDidLoad() { 28 super.viewDidLoad() 29 30 } 31 override func didReceiveMemoryWarning() { 32 super.didReceiveMemoryWarning() 33 // Dispose of any resources that can be recreated. 34 } 35 override func viewDidLayoutSubviews() { 36 // 小さいキャンバスを表示する 37 canvasView = CanvasView(frame: scrollView.bounds) 38 scrollView.addSubview(canvasView) 39 scrollView.contentSize = canvasView.frame.size 40 } 41} 42 43// キャンバスのグリッドの一つ一つのマス目 44class Grid { 45 // 左上 46 var upperLeft: CGPoint! 47 // 右上 48 var upperRight: CGPoint { 49 return CGPoint(x: upperLeft.x + width, y: upperLeft.y) 50 } 51 // 左下 52 var lowerLeft: CGPoint { 53 return CGPoint(x: upperLeft.x, y: upperLeft.y + height) 54 } 55 // 右下 56 var lowerRight: CGPoint { 57 return CGPoint(x: upperLeft.x + width, y: upperLeft.y + height) 58 } 59 60 init(upperLeft: CGPoint) { 61 self.upperLeft = upperLeft 62 } 63 private let width: CGFloat = 30 64 private let height: CGFloat = 20 65} 66 67// キャンバス 68class CanvasView: UIView { 69 // グリッドの一つ一つのマス目を配列で保持する 70 var grids = Array<Grid>() 71 72 override init(frame: CGRect) { 73 super.init(frame: frame) 74 backgroundColor = .yellow 75 initGrid() 76 } 77 // 画面いっぱいのグリッドのマス目を作成する 78 func initGrid() { 79 var point = CGPoint(x: 20, y: 20) 80 while point.y < frame.height { 81 while point.x < frame.width { 82 grids.append(Grid(upperLeft: point)) 83 point.x = point.x + 30 84 } 85 point.x = 20 86 point.y = point.y + 20 87 } 88 } 89 // gridsの各要素について、グリッドを描画する 90 override func draw(_ rect: CGRect) { 91 let path = UIBezierPath(rect: bounds) 92 path.lineWidth = 0.5 93 UIColor.gray.set() 94 95 for grid in grids { 96 path.move(to: grid.upperLeft) 97 path.addLine(to: grid.upperRight) 98 path.addLine(to: grid.lowerRight) 99 path.addLine(to: grid.lowerLeft) 100 path.close() 101 } 102 path.stroke() 103 } 104 required init?(coder aDecoder: NSCoder) { 105 fatalError("init(coder:) has not been implemented") 106 } 107}
補足情報(FW/ツールのバージョンなど)
環境
Xcode Version 9.2 (9C40b)
Swift Version 4.0.3
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/19 07:47 編集
2018/03/19 08:19
2018/03/19 08:39