У меня есть подкласс UIView
, содержащий набор графики, нарисованных с использованием CGPAth
s.Мне нужно знать, когда касание попадает на один из этих путей и какой.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
for p in myDrawnPaths {
if(p.contains(t.location(in: self)) {
doStuffWith(p)
}
}
}
}
Иногда этот код приводит к выполнению doStuffWith()
по нескольким путям, включая те, которые находятся далеко от места попадания,Я провел некоторый осмотр и обнаружил что-то действительно странное в путях, которые не должны быть затронуты:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches {
for p in myDrawnPaths {
print(p.contains(t.location(in: self))) //true
print(p.boundingBox.contains(t.location(in: self))) //false!
}
}
}
А?Разве ограничивающая рамка не должна содержать весь путь, а это означает, что точка внутри пути гарантированно находится внутри ограничительной рамки?
Проблема возникает только в таких тестах - когда я использую CoreGraphics API для рисования ианимируйте с теми же CGPath
с, все изображения отображаются правильно.
ОБНОВЛЕНИЕ
Я пытался воспроизвести проблему с простыми экспериментальными путями в игровых площадках, ноне смог, поэтому мне пришлось взять это из моего фактического приложения.
(75.0, 264.0) is in
Path 0x600003643960:
moveto (252.02, 287.067)
lineto (259.489, 286.324)
lineto (259.567, 286.754)
lineto (263.438, 286.167)
lineto (268.131, 285.503)
lineto (268.17, 285.268)
lineto (268.248, 284.681)
lineto (269.069, 283.235)
lineto (269.851, 282.57)
lineto (269.773, 280.576)
lineto (270.399, 279.95)
lineto (270.829, 279.833)
lineto (270.907, 278.425)
lineto (271.494, 277.252)
lineto (271.924, 277.486)
lineto (272.002, 277.721)
lineto (272.315, 277.799)
lineto (273.058, 277.408)
lineto (272.901, 273.85)
lineto (271.65, 270.643)
lineto (270.751, 267.085)
lineto (269.812, 265.834)
lineto (268.796, 265.13)
lineto (268.17, 265.56)
lineto (266.645, 266.264)
lineto (265.902, 268.219)
lineto (264.846, 269.666)
lineto (264.416, 269.9)
lineto (263.83, 269.666)
curveto (263.83, 269.666) (262.813, 269.079) (262.891, 268.845)
curveto (262.969, 268.61) (263.087, 266.889) (263.087, 266.889)
lineto (264.416, 266.381)
lineto (264.729, 265.052)
lineto (264.964, 264.035)
lineto (265.902, 263.409)
lineto (265.785, 259.499)
lineto (265.159, 258.6)
lineto (264.651, 258.287)
lineto (264.338, 257.466)
lineto (264.651, 257.153)
lineto (265.276, 257.27)
lineto (265.355, 256.644)
lineto (264.338, 255.784)
lineto (263.83, 254.767)
lineto (262.813, 254.767)
lineto (261.053, 254.181)
lineto (258.903, 252.851)
lineto (257.847, 252.851)
lineto (257.612, 253.086)
lineto (257.221, 252.891)
lineto (256.009, 251.991)
lineto (254.875, 252.695)
lineto (253.741, 253.594)
lineto (253.858, 255.002)
lineto (254.249, 255.119)
lineto (255.07, 255.315)
lineto (255.266, 255.628)
lineto (254.249, 255.941)
lineto (253.233, 256.058)
lineto (252.646, 256.762)
lineto (252.529, 257.583)
lineto (252.646, 258.209)
lineto (252.763, 260.359)
lineto (251.356, 261.18)
lineto (251.121, 261.102)
lineto (251.121, 259.46)
lineto (251.629, 258.521)
lineto (251.864, 257.583)
lineto (251.551, 257.27)
lineto (250.808, 257.583)
lineto (250.417, 259.225)
lineto (249.361, 259.655)
lineto (248.657, 260.398)
lineto (248.579, 260.789)
lineto (248.814, 261.102)
lineto (248.579, 262.119)
lineto (247.68, 262.314)
lineto (247.68, 262.745)
lineto (247.993, 263.683)
lineto (247.563, 266.068)
lineto (246.937, 267.632)
lineto (247.172, 269.47)
lineto (247.367, 269.9)
lineto (247.054, 270.839)
lineto (246.937, 271.152)
lineto (246.82, 272.208)
lineto (248.227, 274.554)
lineto (249.361, 277.095)
lineto (249.948, 278.972)
lineto (249.635, 280.81)
lineto (249.244, 283.156)
lineto (248.306, 285.19)
lineto (248.188, 286.246)
lineto (246.937, 287.458)
closepath
moveto (233.916, 259.147)
moveto (233.407, 258.717)
moveto (232.703, 254.65)
moveto (231.257, 254.142)
moveto (230.592, 253.242)
moveto (225.665, 252.148)
moveto (224.57, 251.717)
moveto (221.403, 250.857)
moveto (218.352, 250.466)
moveto (216.827, 248.394)
moveto (217.101, 248.198)
moveto (218.157, 247.885)
moveto (219.565, 246.986)
lineto (219.565, 246.595)
lineto (219.799, 246.36)
lineto (222.145, 245.969)
lineto (223.084, 245.226)
lineto (224.804, 244.405)
lineto (224.883, 243.897)
lineto (225.626, 242.763)
lineto (226.33, 242.45)
lineto (226.838, 241.746)
lineto (227.737, 240.847)
lineto (229.458, 239.908)
lineto (231.296, 239.713)
lineto (231.726, 240.143)
lineto (231.608, 240.534)
lineto (230.162, 240.925)
lineto (229.575, 242.137)
lineto (228.676, 242.45)
lineto (228.48, 243.388)
lineto (227.542, 244.64)
lineto (227.424, 245.656)
lineto (227.737, 245.852)
lineto (228.128, 245.422)
lineto (229.536, 244.288)
lineto (230.044, 244.796)
lineto (230.944, 244.796)
lineto (232.195, 245.187)
lineto (232.782, 245.617)
lineto (233.368, 246.83)
lineto (234.424, 247.885)
lineto (235.949, 247.807)
lineto (236.535, 247.416)
lineto (237.161, 247.924)
lineto (237.787, 248.12)
lineto (238.295, 247.807)
lineto (238.725, 247.807)
lineto (239.351, 247.416)
lineto (240.915, 246.008)
lineto (242.245, 245.578)
lineto (244.825, 245.461)
lineto (246.585, 244.718)
lineto (247.602, 244.21)
lineto (248.188, 244.288)
lineto (248.188, 246.517)
lineto (248.384, 246.634)
lineto (249.518, 246.947)
lineto (250.261, 246.751)
lineto (252.646, 246.126)
lineto (253.076, 245.696)
lineto (253.663, 245.891)
lineto (253.663, 248.628)
lineto (254.914, 249.84)
lineto (255.422, 250.075)
lineto (255.931, 250.466)
lineto (255.422, 250.583)
lineto (255.109, 250.466)
lineto (253.663, 250.271)
lineto (252.842, 250.505)
lineto (251.942, 250.427)
lineto (250.691, 251.014)
lineto (249.987, 251.014)
lineto (247.719, 250.505)
lineto (245.686, 250.583)
lineto (244.943, 251.6)
lineto (242.205, 251.835)
lineto (241.267, 252.148)
lineto (240.837, 253.36)
lineto (240.328, 253.79)
lineto (240.133, 253.712)
lineto (239.546, 253.086)
lineto (237.787, 254.025)
lineto (237.552, 254.025)
lineto (237.122, 253.399)
lineto (236.809, 253.477)
lineto (236.066, 255.198)
lineto (235.675, 256.762)
lineto (234.424, 259.46)
closepath
moveto (222.849, 237.367)
moveto (223.553, 236.545)
moveto (224.413, 236.233)
moveto (226.525, 234.708)
moveto (227.424, 234.473)
moveto (227.62, 234.668)
moveto (225.626, 236.663)
moveto (224.335, 237.406)
moveto (223.514, 237.758)
closepath
moveto (257.221, 250.31)
moveto (257.456, 251.287)
moveto (258.707, 251.365)
moveto (259.215, 250.896)
curveto (259.215, 250.896) (259.176, 250.31) (259.059, 250.271)
curveto (258.942, 250.192) (258.433, 249.528) (258.433, 249.528)
lineto (257.573, 249.606)
lineto (256.947, 249.684)
lineto (256.83, 250.114)
Как мы видим, все точки пути имеют X-координату в 200 с, но точку с X-координатойиз 75 вычисляется, чтобы быть в пределах этого пути.
Проблема исчезнет, если я добавлю команду close
к пути, но это поднимает дополнительные вопросы:
Как CGPath contains
работает на открытых путях, и где, если где-либо, это задокументировано?
Почему это влияет на результаты метода contains
, а не на все, что яувидеть на экране?Например, если я скажу, что соответствующий CALayer
должен быть заполнен определенным цветом, цвет не выливается за пределы, где он должен быть.