如何以编程方式设置 UITableView 标头的约束以支持 RTL 和 LTR?

Posted

技术标签:

【中文标题】如何以编程方式设置 UITableView 标头的约束以支持 RTL 和 LTR?【英文标题】:How to set the constraints for UITableView header programatically to Support both RTL and LTR? 【发布时间】:2017-08-19 09:57:47 【问题描述】:

我正在使用 UITableView 的 viewForHeader 委托来设置自定义标题视图,但我没有设置约束。所以现在我的应用程序也需要支持 RTL 语言。我的代码如下:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: menuTableView.frame.size.width, height: 40))
let headerImage = UIImageView()
headerImage.frame = CGRect(x: 15, y: 15, width: 12, height: 12)
let headerLabel = UILabel()
headerLabel.frame = CGRect(x: headerImage.frame.origin.x + headerImage.frame.size.width + 20, y: 10, width:menuTableView.frame.size.width - 40, height: 20)
headerLabel.font = UIFont().robotoLight(withFontSize: 9)
headerLabel.textColor = CustomColor.menuGrey.color
let arrowImage = UIImageView()
arrowImage.isHidden = true
switch section 
case 1:
  headerImage.image = UIImage(named: "home_icon")
  headerLabel.text = "Home"
case 2:
  headerImage.image = UIImage(named: "my_Id_icon")
  headerLabel.text = "My ID"
case 3:
  headerImage.image = UIImage(named: "my_interest_icon")
  headerLabel.text = "My Account"
  arrowImage.isHidden = false
  if isFirstSectionHidden 
    arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 3, height: 5)
    arrowImage.image = UIImage(named: "side_arrow")
   else 
    arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 5, height: 3)
    arrowImage.image = UIImage(named: "down_arrow")
  
case 4:
  headerImage.image = UIImage(named: "my_profile_icon")
  headerLabel.text = "My Profile"
case 5:
  headerImage.image = UIImage(named: "language_icon")
  headerLabel.text = language
  arrowImage.isHidden = false
  if isSecondSectionHidden 
    arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 3, height: 5)
    arrowImage.image = UIImage(named: "side_arrow")
   else 
    arrowImage.frame = CGRect(x: menuTableView.frame.size.width - 30, y: 15, width: 5, height: 3)
    arrowImage.image = UIImage(named: "down_arrow")
  

case 6:
  headerImage.image = UIImage(named: "notification_icon")
  headerLabel.text = "Notifications"
case 7:
  headerImage.image = UIImage(named: "about_us_icon")
  headerLabel.text = "About Us"
case 8:
  headerImage.image = UIImage(named: "faq_icon")
  headerLabel.text = "FAQ"
case 9:
  headerImage.image = UIImage(named: "contact_us_icon")
  headerLabel.text = "Contact Us"
case 10:
  headerImage.image = UIImage(named: "logout_icon")
  headerLabel.text = "Logout"
default:
  print("Something else")


let headerClick = UIButton(type: .custom)
headerClick.addTarget(self, action: #selector(self.headerAction), for: .touchUpInside)
headerClick.frame = CGRect(x: 0, y: 0, width: menuTableView.frame.size.width, height: 40)
headerClick.tag = section
headerClick.backgroundColor = UIColor.clear
headerView.addSubview(arrowImage)
headerView.addSubview(headerLabel)
headerView.addSubview(headerImage)
headerView.addSubview(headerClick)
return headerView

如何以编程方式设置 headerView 、 headerImage 和 headerLabel 的框架和约束以支持 LTR 和 RTL?

这是 UITableView 的示例图像:

【问题讨论】:

如果你使用约束,那么你可以使用“前导”和“尾随”约束(不是“左”和“右”),当设备处于 RTL 语言环境时,系统会自动调整。有约束您没有明确设置框架 是的,我明白.. 请您帮我以编程方式设置上述代码约束? 【参考方案1】:

我不确定我是否正确理解了您的布局,但它应该像这样工作:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    return 50


override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    let headerView = UIView()
    headerView.backgroundColor = .lightGray

    let headerImage = UIImageView()
    headerImage.translatesAutoresizingMaskIntoConstraints = false
    headerImage.backgroundColor = .red
    headerImage.widthAnchor.constraint(equalToConstant: 12).isActive = true
    headerImage.heightAnchor.constraint(equalToConstant: 12).isActive = true

    let headerLabel = UILabel()
    headerLabel.translatesAutoresizingMaskIntoConstraints = false
    headerLabel.backgroundColor = .blue

    let arrowImage = UIImageView()
    arrowImage.translatesAutoresizingMaskIntoConstraints = false
    arrowImage.backgroundColor = .green
    arrowImage.widthAnchor.constraint(equalToConstant: 5).isActive = true
    arrowImage.heightAnchor.constraint(equalToConstant: 5).isActive = true

    let headerClick = UIButton()
    headerClick.translatesAutoresizingMaskIntoConstraints = false
    headerClick.backgroundColor = .clear
    headerClick.isOpaque = false

    headerView.addSubview(headerImage)
    headerView.addSubview(headerLabel)
    headerView.addSubview(arrowImage)
    headerView.addSubview(headerClick)

    var constraints = [NSLayoutConstraint]()
    constraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "|-15-[hi]-[hl]-[ai]-15-|", options: [.alignAllCenterY], metrics: nil, views: ["hi": headerImage, "hl": headerLabel, "ai": arrowImage]))
    constraints.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[hl]-10-|", options: [], metrics: nil, views: ["hl": headerLabel]))
    NSLayoutConstraint.activate(constraints)

    headerClick.widthAnchor.constraint(equalTo: headerView.widthAnchor).isActive = true
    headerClick.heightAnchor.constraint(equalTo: headerView.heightAnchor).isActive = true

    return headerView

我只设置了通用布局。您仍然必须添加自定义逻辑。这是它的样子:

【讨论】:

请务必在 Github 上发布示例项目。 "|-15-[hi]-[hl]-[ai]-15-|" V:|-10-[hl]-10-| .它们是什么意思??请告诉..

以上是关于如何以编程方式设置 UITableView 标头的约束以支持 RTL 和 LTR?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式设置 UITableView 的高度

如何以编程方式设置 UITableView 部分标题(iPhone/iPad)?

如何使用自动布局以编程方式创建 UITableView?

如何拥有具有两种不同单元格类型的 UITableView 并以编程方式设置每个单元格布局,而不是通过情节提要?

如何以编程方式从情节提要中填充静态 UITableView?

从.NET调用WCF服务时如何以编程方式添加soap标头?