19

我试图找出如何计算今日扩展主视图中的左边距,以将内容与今日视图标签的其余部分对齐。

这是一个使用 Today 扩展的干净 Xcode 项目的示例(我为视图背景添加了颜色并绘制了一条红色虚线来说明我想在哪里对齐 Hello World UILabel)。

iPhone 6 Plus 模拟器中的结果(左侧横向,右侧纵向)可以从下图中找到:

在此处输入图像描述

在图像中,请注意绿色主视图左边界与应用名称UILabel“testi2”相关的位置不同。似乎红线 - 主视图左边框对齐在每个设备中都不同:iPhone 5x、iPhone 6 和 iPad。

可以使用干净的 Xcode 项目重现该行为(我使用的是 Xcode 6.1.1、iOS 8.1 和 Swift):

  1. 创建一个空的 Xcode 项目(单视图应用程序)
  2. 添加新目标:扩展 > 今天扩展
  3. 从 Today 扩展组中,找到 MainInterface.storyboard 并将主视图背景设为绿色,Hello worldUILabel背景设为红色: 在此处输入图像描述

如何将 Hello World UILabel(红色背景)与虚线对齐?或者如何将主视图(绿色背景)与虚线对齐?

4

3 回答 3

17

你试过这个吗?

目标-C

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets
{
    return UIEdgeInsetsZero;
}

迅速:

func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets {
        return UIEdgeInsetsZero
}

否则看起来你将不得不根据这个So-Thread手动设置它们:

编辑:

看起来此方法已被弃用,并且不会为运行 >= iOS10 的设备调用。但是我找不到任何关于替代方案的文档。如果您对此有任何信息,请添加到此帖子中,以便每个人都可以获利。只需确保在使用此功能时不会在 >= iOS10 上调用它

资料来源:苹果文档

于 2015-01-02T10:29:27.670 回答
6

我尝试使用 of 的值left,结果喜忧参半:在 iPhone 5S 屏幕尺寸上,它可用于获取与 iOS 的默认日历小部件相同的插图(注意时间标签的右边距与蓝线对齐):defaultMarginInset-widgetMarginInsetsForProposedMarginInsets

5S人像

5S景观

在 iPhone 6 上,您会得到类似的结果,即它也对齐。但是,在 iPhone 6 Plus 上,日历小部件会以某种方式缩放插图:

6P人像

6P风景

请注意,在横向版本中,时间和线条都不与任何内容对齐。

总之,我想说你可以安全地使用它defaultMarginInset.left来获得体面的结果。


SWIFT代码:

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)
    }
}
于 2015-01-02T11:09:27.713 回答
4

我的临时解决方案如下。我使用常量值来设置左边距和上边距。通过这种方式,我可以将内容完全对齐,例如,在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
}

但是,这不是我正在寻找的解决方案 - 我想摆脱对每个设备每个方向的像素值进行硬编码。

于 2015-01-02T14:28:36.723 回答