ios - 以编程方式在 tableView 和 BottomLayoutGuide 之间添加 View

标签 ios swift uitableview uiviewcontroller admob

我有一个 UIViewController 和一个 UITableView,它填充了支持广告的版本的屏幕。 MyViewController 嵌入在 UINavigationController 中,并且底部有一个 UITabBarController

此应用程序将有 2 个版本:

1) 付费 - 我在 Storyboard上配置了此功能。它按预期工作。

2) 支持广告 - 尽管我尽力了,但还是无法将横幅绘制在正确的位置。我正在尝试这样做:

topLayoutGuide
tableview
standard height padding
bannerView (50 height)
standard height padding
bottomLayoutGuide

相反,bannerView 绘制在 tableView 的顶部,而不是在 tableViewbottomLayoutGuide 之间绘制

enter image description here

我从 viewDidLoad 调用我创建的名为 configureBannerView 的方法。这是用视觉格式语言布置 View 的代码的相关部分:

var allConstraints = [NSLayoutConstraint]()

let horizontalTableViewConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
    "H:|[tableView]|",
    options: NSLayoutFormatOptions.AlignAllCenterY,
    metrics: nil,
    views: views)
allConstraints += horizontalTableViewConstraint

let horizontalBannerViewConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
    "H:|[leftBannerViewSpacer]-[bannerView(320)]-[rightBannerViewSpacer(==leftBannerViewSpacer)]|",
    options: NSLayoutFormatOptions.AlignAllCenterY,
    metrics: nil,
    views: views)
allConstraints += horizontalBannerViewConstraint

let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
    "V:|[topLayoutGuide][tableView]-[leftBannerViewSpacer(50)]-[bottomLayoutGuide]|",
    options: [],
    metrics: metrics,
    views: views)
    allConstraints += verticalConstraints

我不明白为什么这不起作用。下面是完整的 configureBannerView 方法。

func configureBannerView() {
    if adSupported == false {
        // Do nothing, leave it alone
    } else {

        // remove existing constraints
        tableView.removeConstraints(tableView.constraints)
        tableView.translatesAutoresizingMaskIntoConstraints = false

        // create dictionary of views
        var views: [String : AnyObject] = [
            "tableView" : tableView,
            "topLayoutGuide": topLayoutGuide,
            "bottomLayoutGuide": bottomLayoutGuide]

        // Create a frame for the banner
        let bannerFrame = CGRect(x: 0, y: 0, width: kGADAdSizeBanner.size.width, height: kGADAdSizeBanner.size.height)
        // Instnatiate the banner in the frame you just created
        bannerView = GADBannerView.init(frame: bannerFrame)
        bannerView?.translatesAutoresizingMaskIntoConstraints = false
        // add the bannerView to the view
        view.addSubview(bannerView!)
        // add bannerView to the view dictionary
        views["bannerView"] = bannerView

        // Create spacers for left and right sides of bannerView
        // 32.0 = leftSpacer left pad + leftSpacer right pad + rightSpacer left pad + rightSpacer right pad
        // Calculate width of spacer
        let spacerWidth = (screenSize.width - kGADAdSizeBanner.size.width - 32.0) / 2

        // Instantiate left and right pads
        // 50.0 = height of bannerView
        let leftBannerViewSpacer = UIView(frame: CGRect(x: 0, y: 0, width: spacerWidth, height: 50.0))
        let rightBannerViewSpacer = UIView(frame: CGRect(x: 0, y: 0, width: spacerWidth, height: 50.0))

        leftBannerViewSpacer.translatesAutoresizingMaskIntoConstraints = false
        rightBannerViewSpacer.translatesAutoresizingMaskIntoConstraints = false

        // add the spacers to the subview
        view.addSubview(leftBannerViewSpacer)
        view.addSubview(rightBannerViewSpacer)

        // add to the views dictionary
        views["leftBannerViewSpacer"] = leftBannerViewSpacer
        views["rightBannerViewSpacer"] = rightBannerViewSpacer


        // Create metric for tabBarHeight
        let tabBarHeight = tabBarController?.tabBar.frame.height

        // Create a dictionary of metrics
        let metrics: [String : CGFloat] = ["tabBarHeight": tabBarHeight!]


        var allConstraints = [NSLayoutConstraint]()

        let horizontalTableViewConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
            "H:|[tableView]|",
            options: NSLayoutFormatOptions.AlignAllCenterY,
            metrics: nil,
            views: views)
        allConstraints += horizontalTableViewConstraint

        let horizontalBannerViewConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
            "H:|[leftBannerViewSpacer]-[bannerView(320)]-[rightBannerViewSpacer(==leftBannerViewSpacer)]|",
            options: [NSLayoutFormatOptions.AlignAllCenterY],
            metrics: nil,
            views: views)
        allConstraints += horizontalBannerViewConstraint

        let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(
            "V:|[topLayoutGuide][tableView]-[leftBannerViewSpacer(50)]-[bottomLayoutGuide]|",
            options: [],
            metrics: metrics,
            views: views)
        allConstraints += verticalConstraints

        NSLayoutConstraint.activateConstraints(allConstraints)

感谢您的阅读。我欢迎提出解决我的错误代码的建议。

最佳答案

Storyboard解决方案

除非所有其他途径都失败,否则不要以编程方式添加约束:在构建、链接、运行之前,无法看到您正在做什么。

需要更少代码的更简单的解决方案是保留 View 的引用和 Interface Builder 的约束,并且:

constraintToTweak.constant = newValue

Unlike the other properties, the constant may be modified after constraint creation. Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant.

constraintToTweak.active = false

The receiver may be activated or deactivated by manipulating this property.  Only active constraints affect the calculated layout.  Attempting to activate a constraint whose items have no common ancestor will cause an exception to be thrown. Defaults to NO for newly created constraints.

关于ios - 以编程方式在 tableView 和 BottomLayoutGuide 之间添加 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35071557/

相关文章:

javascript - ios 在 Canvas 上绘制图像并显示 :none causes memory leak

ios - 我在 pod install Kanna 时遇到错误

ios - 点击后退按钮时在 View 中显示消息

iphone - 在 'UITableView' 中选择一行时调用新 View

ios - CollectionView 上的最后一个单元格无法在 Swift 中看到

ios - 如何删除CSSearchableItemAttributeSet中的thumbnailData

ios - MCSessionDelegate 要求类符合 NSObjectProtocol

ios - Swift - 从 NSDate 中提取小时数,解析字符串问题

ios - UITableView 重新加载数据确实适用于 IOS 7,但适用于 IOS Simulator

iOS 7 TableView 就像 iPad 上的“设置”应用程序中一样