Как правильно определить левый край верхнего уровня Today в iOS 8?
Я пытаюсь выяснить, как вычислить левое поле в главном окне расширения Today, чтобы выровнять содержимое с остальными метками представления Today.
Вот пример с чистым проектом Xcode с использованием расширений Today (я добавил цвет к фону представления и нарисовал пунктирную красную линию, чтобы проиллюстрировать, где я хотел бы выровнять Hello World UILabel
).
Результат в симуляторе iPhone 6 Plus (левый альбом, правый портрет) можно найти на изображении ниже:
![enter image description here]()
На изображении обратите внимание, что левая граница зеленого главного изображения по-разному связана с именем приложения UILabel
"testi2". Также кажется, что красная линия - основные виды слева выравнивания границы различны в каждом устройстве: iPhone 5x, iPhone 6 и iPads.
Поведение может быть воспроизведено с использованием чистого проекта Xcode (я использую Xcode 6.1.1, iOS 8.1 и Swift):
- Создать пустой проект Xcode (одноразовое приложение)
- Добавить новую цель: Расширения > Расширение Today
- В расширенной группе "Сегодня" найдите MainInterface.storyboard и сделайте основной фон для фона зеленым и Hello world
UILabel
background red:
![enter image description here]()
Как выровнять строку Hello World UILabel
(красный фон) пунктирной линией? Или как выровнять основной вид (зеленый фон) с пунктирной линией?
Ответы
Ответ 1
Вы попробовали этот?
Objective-C
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets
{
return UIEdgeInsetsZero;
}
Swift:
func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets {
return UIEdgeInsetsZero
}
В противном случае вам будет необходимо установить их вручную в соответствии с этим So-Thread:
EDIT:
Похоже, этот метод устарел и не вызывается для устройств с запуском >= iOS10. Однако я не мог найти никакой документации по альтернативе. Если у вас есть какая-либо информация по этому вопросу, пожалуйста, добавьте к этому сообщению, чтобы каждый мог получить прибыль. Просто убедитесь, что при использовании этой функции она не будет вызываться нa >= iOS10.
Источник: Документация Apple
Ответ 2
Я попытался использовать значение left
defaultMarginInset
of -widgetMarginInsetsForProposedMarginInsets
со смешанными результатами: на габаритах экрана iPhone 5S его можно использовать для получения той же вставки, что и виджет календаря по умолчанию для iOS (обратите внимание, что правый край метки времени совпадает с синей линией):
![5S Portrait]()
![5S Landscape]()
На iPhone 6 вы получаете похожие результаты, то есть также выравнивает. Однако на iPhone 6 Plus календарный виджет как-то масштабирует вставку:
![6P Portrait]()
![6P Landscape]()
Обратите внимание, что в альбомной версии ни время, ни строки не выравниваются ни с чем.
В заключение я бы сказал, что вы можете безопасно использовать defaultMarginInset.left
для получения достойных результатов.
Быстрый код:
class TodayViewController: UIViewController, NCWidgetProviding {
var defaultLeftInset: CGFloat = 0
var marginIndicator = UIView()
override func viewDidLoad() {
super.viewDidLoad()
marginIndicator.backgroundColor = UIColor.whiteColor()
view.addSubview(marginIndicator)
}
func widgetMarginInsetsForProposedMarginInsets(var defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets {
defaultLeftInset = defaultMarginInsets.left
defaultMarginInsets.left = 0
return defaultMarginInsets
}
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
marginIndicator.frame = CGRectMake(defaultLeftInset, 0, 10, view.frame.size.height)
completionHandler(NCUpdateResult.NewData)
}
}
Ответ 3
Мое временное решение выглядит следующим образом. Я использую постоянные значения для установки левого и верхнего полей. Таким образом, я могу выровнять содержимое точно так же, как это, например, в виджетах Tomorrow Summary.
Сначала некоторые вспомогательные методы для определения типа устройства (адаптированы из этого ответа):
struct ScreenSize {
static let SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
static let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH,
ScreenSize.SCREEN_HEIGHT)
static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH,
ScreenSize.SCREEN_HEIGHT)
}
struct DeviceType {
static let iPhone4 = UIDevice.currentDevice().userInterfaceIdiom == .Phone
&& ScreenSize.SCREEN_MAX_LENGTH < 568.0
static let iPhone5 = UIDevice.currentDevice().userInterfaceIdiom == .Phone
&& ScreenSize.SCREEN_MAX_LENGTH == 568.0
static let iPhone6 = UIDevice.currentDevice().userInterfaceIdiom == .Phone
&& ScreenSize.SCREEN_MAX_LENGTH == 667.0
static let iPhone6Plus = UIDevice.currentDevice().userInterfaceIdiom == .Phone
&& ScreenSize.SCREEN_MAX_LENGTH == 736.0
static let iPad = UIDevice.currentDevice().userInterfaceIdiom == .Pad
}
Затем, используя предложение widgetMarginInsetsForProposedMarginInsets:
, я переписал левую и верхнюю вставки следующим образом:
func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets)
-> UIEdgeInsets {
var insets = defaultMarginInsets
let isPortrait = UIScreen.mainScreen().bounds.size.width
< UIScreen.mainScreen().bounds.size.height
insets.top = 10.0
if DeviceType.iPhone6Plus {
insets.left = isPortrait ? 53.0 : 82.0
} else if DeviceType.iPhone6 {
insets.left = 49.0
} else if DeviceType.iPhone5 {
insets.left = 49.0
} else if DeviceType.iPhone4 {
insets.left = 49.0
} else if DeviceType.iPad {
insets.left = isPortrait ? 58.0 : 58.0
}
return insets
}
Однако это не то решение, которое я ищу - я бы хотел избавиться от жесткого кодирования для пиксельных значений на устройство для ориентации.