首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以编程方式在tableView和bottomLayoutGuide之间添加视图

以编程方式在tableView和bottomLayoutGuide之间添加视图
EN

Stack Overflow用户
提问于 2016-01-28 20:38:25
回答 3查看 939关注 0票数 2

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

这个应用程序将有两个版本:

1)付费-我在故事板上配置了这个。它可以按需要工作。

2)广告支持的--尽管我可以尝试,但我无法在正确的位置画横幅。我想这么做:

代码语言:javascript
运行
复制
topLayoutGuide
tableview
standard height padding
bannerView (50 height)
standard height padding
bottomLayoutGuide

相反,bannerView是在tableView之上绘制的,而不是在tableViewbottomLayoutGuide之间绘制的。

我调用了我从viewDidLoad创建的名为viewDidLoad的方法。下面是用Visual语言展示视图的代码的相关部分:

代码语言:javascript
运行
复制
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方法。

代码语言:javascript
运行
复制
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)

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-28 21:57:13

故事板解决方案

除非所有其他途径都失败了,否则不要以编程方式添加约束:在构建、链接和运行之前,无法查看正在执行的操作。

一个更简单的解决方案需要的代码要少得多,就是保留对视图的引用--一个来自Interface的约束,并且:

代码语言:javascript
运行
复制
constraintToTweak.constant = newValue

与其他属性不同,常数可以在创建约束后进行修改。在现有约束上设置常量比删除约束和添加一个新的约束要好得多,这个约束和旧的一样,但是有一个新的常量。

代码语言:javascript
运行
复制
constraintToTweak.active = false

通过操作此属性,接收方可能被激活或停用。只有活动约束才会影响计算的布局。如果试图激活没有共同祖先的约束,则会引发异常。对于新创建的约束,默认值为NO。

票数 1
EN

Stack Overflow用户

发布于 2016-01-29 04:58:44

SwiftArchitect'sishaq的帮助下,我找到了答案。事实证明,让GADBannerView正确地在UITableView下面显示而不将它添加为页脚的关键是非常简单的。最后,通过执行以下操作,我削减了100行不必要的代码:

1) UIStackView:如果您以前没有使用过它,那么停止您现在正在做的事情,然后遵循本教程

我将tableView: UITableView和接口生成器中的bannerView: GADBannerView添加到垂直UIStackView中。

2)我在IBOutlets上为他们两人创建了tableView (我已经拥有了tableView)。

3)我的重构的configureBannerView看起来是这样的。

代码语言:javascript
运行
复制
// I added these properties at the top. I did not know you could drag 
// constraints from Interface Builder onto the ViewController
@IBOutlet weak var bannerViewHeight: NSLayoutConstraint!
@IBOutlet weak var bannerViewWidth: NSLayoutConstraint!


func configureBannerView() {
    if adSupported == true {
        loadAd() // follow Google's documentation to configure your requests
    } else {
        bannerView.hidden = true // this hides the bannerView if it's not needed

    // Removes constraint errors when device is rotated
    bannerViewWidth.constant = 0.0  
    bannerViewHeight.constant = 0.0

    }
}

感谢SwiftArchitect和ishaq为我指明了正确的方向。

票数 1
EN

Stack Overflow用户

发布于 2020-01-20 02:30:17

添加了一个新的adMob UIViewController作为根控制器和旧根控制器的addSubview。

我有一个编程上非常类似的问题,需要将adMob添加到UITabBarController根控制器中,其中的选项卡控制器是UINavigationController。它们都在试图在内部调整大小时遇到了困难,广告只是在应用程序视图上输入。我可能还不够幸运找到这样一条路。阅读大量的Stackoverflow和Google提示。

我还相信苹果和谷歌的推荐就像让把下面的广告和应用程序分开,但很紧。Android广告横幅以同样的方式出现,同样的行为也是需要的。(最近安卓系统也做了同样的项目)。

制作了一种新的应用程序根控制器,一个带有Admob的ViewController。

为了在未来的项目中实现可重用和顺利实现,需要输入一个新的adUnitID (以及旧根控制器的名称)。横幅将在应用程序屏幕下方。

只需将这个类文件添加到项目中,并使其成为AppDelegate.swift文件中的根控制器。

代码语言:javascript
运行
复制
import UIKit
import GoogleMobileAds

class AdsViewController: UIViewController, GADBannerViewDelegate {

    let adsTest         = true
    let ads             = true //false // 
    let adUnitIDTest    = "ca-app-pub-3940256099942544/2934735716"
    let adUnitID        = "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx"
    let tabVc           = MainTabBarController()

    var bannerView: GADBannerView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Add the adMob banner
        addBanner(viewMaster: view)
        // Add the old root controller as a sub-view
        view.addSubview(tabVc.view)
        // Make its constraints to fit the adMob
        if(ads) {
            tabVc.view.translatesAutoresizingMaskIntoConstraints = false
            tabVc.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            tabVc.view.bottomAnchor.constraint(equalTo: bannerView.topAnchor).isActive = true
            tabVc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            tabVc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        // To be notified of rotation
        NotificationCenter.default.addObserver(self, selector: #selector(AdsViewController.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
        }
    }

/*******************************

Ads banner standard engine

*******************************/

    func addBanner(viewMaster: UIView) {
        if(ads) {
            // We instantiate the banner with desired ad size.
            bannerView = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
            addBannerViewToView(bannerView, viewMaster: viewMaster)
            if(adsTest) {
                bannerView.adUnitID = adUnitIDTest
            } else {
                bannerView.adUnitID = adUnitID
            }

            bannerView.rootViewController = self
            bannerView.load(GADRequest())
            bannerView.delegate = self
        }
    }

    func addBannerViewToView(_ bannerView: GADBannerView, viewMaster: UIView) {
        bannerView.translatesAutoresizingMaskIntoConstraints = false
        viewMaster.addSubview(bannerView)
        viewMaster.addConstraints(
        [NSLayoutConstraint(item: bannerView,
                            attribute: .bottom,
                            relatedBy: .equal,
                            toItem: viewMaster.safeAreaLayoutGuide,
                            attribute: .bottom,
                            multiplier: 1,
                            constant: 0),
         NSLayoutConstraint(item: bannerView,
                            attribute: .centerX,
                            relatedBy: .equal,
                            toItem: viewMaster,
                            attribute: .centerX,
                            multiplier: 1,
                            constant: 0)
        ])
    }

/*******************************

Rotation (change SmartBanner)

*******************************/
    @objc func rotated() {
        if UIDevice.current.orientation.isPortrait {
            bannerView.adSize = kGADAdSizeSmartBannerPortrait

        }
        if UIDevice.current.orientation.isLandscape {
            bannerView.adSize = kGADAdSizeSmartBannerLandscape
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35071557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档