草庐IT

ios - 如何在 iPhone X 上居中自定义标签栏项目

coder 2023-09-11 原文

我有一个应用程序,我在 UITabbarController 中创建了一个自定义选项卡栏项目,有人可以按下它来拍照,它看起来像下面这样。

这正是我想要的,问题是当我在 iPhone X 上测试它时,相机的标签栏项目看起来比我想要的要低,例如:

我已经尝试了一些方法来解决这个问题,比如在 viewDidLayoutSubviews() 中修复标签栏的高度,但它弄乱了 iPhone 8 上的标签栏。我还确保“使用安全区域布局”指南”被选中,但它仍然不起作用。

我也尝试过更改标签栏项的框架,但这也不起作用。

这是我用于自定义标签栏 Controller 的代码:

    import UIKit

class OtherTabController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        setupBtn()
        // Do any additional setup after loading the view.
    }





    func setupBtn() {
        let centerBtn = UIButton(frame: CGRect(x: 0, y: 10, width: 45, height: 45))

        var centerBtnFrame = centerBtn.frame
        centerBtnFrame.origin.y = (view.bounds.height - centerBtnFrame.height) - 2
        centerBtnFrame.origin.x = view.bounds.width/2 - centerBtnFrame.size.width/2
        centerBtn.frame = centerBtnFrame

        centerBtn.layer.cornerRadius = 35
        view.addSubview(centerBtn)
        let centerImg = UIImage(named: "Other")

        centerBtn.setBackgroundImage(centerImg, for: .normal)
        centerBtn.addTarget(self, action: #selector(centerBtnAction(sender:)), for: .touchUpInside)
        view.layoutIfNeeded()

    }


    @objc private func centerBtnAction(sender: UIButton) {
        print("Camera")
        cameraAction()
    }

    func cameraAction() {
        let alertController = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet)
        let takePhotoAction = UIAlertAction(title: "Take a Photo", style: .default, handler: nil)
        alertController.addAction(takePhotoAction)
        let selectFromAlbumAction = UIAlertAction(title: "Select from Album", style: .default, handler: nil)
        alertController.addAction(selectFromAlbumAction)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
        //OtherTabController?.present(alertController, animated: true, completion: nil)
    }
}

如果还有什么我可以帮忙的,请尽管问。谢谢

编辑:

我试图使 y View 与 super View 相同,但它所做的只是将按钮移动到屏幕顶部。

    var centerBtnFrame = centerBtn.frame
centerBtnFrame.origin.y = view.bounds.minY //Make centerBtn' top equal to that of view's
centerBtnFrame.origin.x = view.bounds.width/2 - centerBtnFrame.size.width/2
centerBtn.frame = centerBtnFrame

如果您需要更多信息,请询问。谢谢


编辑: 在@Revanth Kausikan 的帮助下,我决定创建一个带有 View 和一些按钮的自定义标签栏。在我看来它工作得很好。它的边缘看起来有点粗糙,但这只是目前的测试。

这是 View 的代码:

    import UIKit

class ItemScene: UIViewController {


    @IBOutlet var customTab: UIView!

    @IBOutlet weak var cameraBtn: UIButton!

    @IBOutlet weak var twoBtn: UIButton!
    @IBOutlet weak var oneBtn: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()


    }

    @IBAction func cameraBtnPressed(_ sender: Any) {
        print("Camera")
    }


    @IBAction func twoBtnPressed(_ sender: Any) {
        self.performSegue(withIdentifier: "segue", sender: nil)
        print("Two")
    }


    @IBAction func oneBtnPressed(_ sender: Any) {
        print("One")
    }


}

这是第二个 ViewController 的代码:

    import UIKit

class TestingViewController: UIViewController {

    @IBOutlet weak var cameraBtn: UIButton!

    @IBOutlet weak var oneBtn: UIButton!

    @IBOutlet weak var twoBtn: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }


    @IBAction func cameraBtnPressed(_ sender: Any) {
        print("Camera")
    }


    @IBAction func twoBtnPressed(_ sender: Any) {

        print("Two")
    }

    @IBAction func oneBtnPressed(_ sender: Any) {
        performSegueToReturnBack()
        print("One")
    }
}


extension UIViewController {
    func performSegueToReturnBack()  {
        if let nav = self.navigationController {
            nav.popViewController(animated: true)
        } else {
            self.dismiss(animated: true, completion: nil)
        }
    }
}

如果有人有任何补充,将不胜感激。谢谢

最佳答案

按钮框架的 Y 点必须与其父 View (即此处的标签栏)的 Y 点相同。

如果您还没有为标签栏创建导出,请先创建。

  1. 按住 Ctrl(或右键)单击并从 Storyboard中的选项卡栏拖动到其关联的 View Controller ,以创建一个 socket 。 (假设我将其命名为 tabBar)

  2. 现在试试这个:

var centerBtnFrame = centerBtn.frame
let tabBarFrame = self.convert(tabBar.frame, to: view) 
centerBtnFrame.origin.y = tabBarFrame.minY //Make centerBtn' top equal to that of tabBar's
centerBtnFrame.origin.x = view.bounds.width/2 - centerBtnFrame.size.width/2
centerBtn.frame = centerBtnFrame

或者,你可以试试这个:

var centerBtnFrame = centerBtn.frame
centerBtnFrame.origin.y = view.height - tabBar.height //This is the same logic as you've used for fixing x value of centerBtnFrame.
centerBtnFrame.origin.x = view.bounds.width/2 - centerBtnFrame.size.width/2
centerBtn.frame = centerBtnFrame

另一种方法是返回到约束,并确保元素和基础 View 在安全区域内。

如果我的猜测是正确的(因为你没有在问题中提供有关约束的详细信息),你已经将基本 View (位于底部/底部的 View ,包含所有其他元素)设置为适合 View Controller 的整个 View 。考虑更改它以适应安全区域。

让我知道结果。

编辑

我对您的新尝试的看法:它真的很好,而且我看到您现在可以对其进行更多自定义。

要改进它,您可以尝试这些:

这里有三个本质上可点击的 View 。我们可以根据自己的意愿使用它来增加交互区域,为用户提供自然的体验。

这是它的限制条件:

除了这些建议,我认为我不需要提供任何其他建议。您的方法足以满足您的实现想法。

:)

关于ios - 如何在 iPhone X 上居中自定义标签栏项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56095750/

有关ios - 如何在 iPhone X 上居中自定义标签栏项目的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  6. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  7. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  8. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐