#ios #swift #uibarbuttonitem
#iOS #swift #uibarbuttonitem
Вопрос:
Я пытаюсь настроить пошаговое руководство по новой функции для своих пользователей, и как часть этого я хотел бы нарисовать круг вокруг соответствующего элемента пользовательского интерфейса. Я пытаюсь нарисовать круг вокруг UIBarButtonItem в правом верхнем углу панели навигации, но когда я перевожу координаты фрейма в главное окно, что-то в математике не так, и красный круг смещен слишком далеко вправо.
На скриншоте я пытаюсь нарисовать красный круг вокруг второй кнопки (на которую указывает всплывающее окно), но когда я перевожу координаты, он фактически рисуется вокруг 3-й кнопки. Когда я запускаю тот же код на первой кнопке (поисковое увеличительное стекло), он работает просто отлично, и красный круг нарисован правильно.
В моем коде я просто беру barButtonItem
из всплывающего окна, и я проверил, что он указывает на правильную кнопку.
if let buttonItem = self.popoverPresentationController?.barButtonItem {
if let view = buttonItem.value(forKey: "view") as? UIView,
let mainView = containingViewController?.navigationController?.view {
let viewFrame = view.frame
print("viewFrame: (viewFrame)")
// This should be translating coords to the main window.
let windowRect = view.convert(viewFrame, to: nil)
print("Window RECT (windowRect)")
let circlePath = UIBezierPath(ovalIn: windowRect)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 3.0
mainView.layer.addSublayer(shapeLayer)
}
}
Я распечатываю view
фрейм, и эти цифры кажутся правильными, но переведенный windowRect
отключен, когда это не самая левая кнопка на навигационной панели.
Для кнопки поиска (самая левая на скриншоте):
viewFrame: (0.0, 0.0, 46.0, 44.0)
Window RECT (617.0, 27.0, 46.0, 44.0)
Для второй кнопки (на которую указывает всплывающее окно на скриншоте) прямоугольник окна смещен на 108 вместо 54, как ожидалось:
viewFrame: (54.0, 0.0, 46.0, 44.0)
Window RECT: (725.0, 27.0, 46.0, 44.0)
Каждый UIBarButtonItem имеет ширину 46, и я предполагаю, что интервал между ними равен 8. Это дает начальный x 54.0 во втором наборе чисел. Но при переводе в координаты окна каким-то образом это становится разницей в 108; так что это компенсируется целой кнопкой. Я пытался настроить таргетинг на 3-ю и 4-ю кнопки, и он всегда отключен на одну полную ширину кнопки. Как вы можете видеть, красный круг сосредоточен на 3-й кнопке, но это не та, которую я пытаюсь выделить.
Я пытался перевести в mainView
вместо to: nil
при выполнении view.convert
, но это не имеет никакого значения. Цифры возвращаются точно такими же. Есть мысли о том, что я делаю неправильно, или это «но» (известное или иное), и мне придется делать сумасшедшие вещи в моем коде, чтобы заставить его работать правильно?
Обновлено, чтобы добавить: Если я удалю перевод и просто помещу слой в супервизию того вида, который я нашел:
let circlePath = UIBezierPath(ovalIn: viewFrame)
// code to create shapelayer
view.superview?.layer.addSublayer(highlightItemLayer!)
Тогда он отображается в правильном месте. Я бы хотел, чтобы он был выше в иерархии представлений, чтобы я мог нарисовать его поверх других вещей; поэтому все еще хочу иметь возможность выполнять перевод, если это возможно.
Комментарии:
1. Вы уверены, что это не сетчатка?
2. Я тестирую в симуляторе на ipad pro 11 «, используя iOS 13.3. Как бы я определил, была ли это сетчатка? Другое поле, которое я пытаюсь обвести, также выходит немного сдвинутым вниз и вправо на том же симуляторе. Это заставляет меня думать, что перевод не учитывает маржу или что-то в этом роде. Я делал другие подобные переводы, когда пользователь нажимал на экран, и они были прекрасными.
3. Когда я удаляю перевод во 2-м поле (не в UIBarButtonItem), он работает отлично. что-то определенно не так в том, как я делаю перевод, или как происходит перевод.
Ответ №1:
Я думаю, что я решил это. Я изменил строку преобразования с let windowRect = view.convert(viewFrame, to: nil)
, чтобы использовать супервизор вместо просто представления:
let windowRect = view.superview?.convert(viewFrame, to: nil)
и теперь красный круг отображается в соответствующем месте (обратите внимание, что я также увеличил его размер, используя translatedFrame.insetBy(dx: -10, dy: -10)
в windowRect перед созданием пути.