【问题标题】:Is it possible to set the alignment of segmented Control titles to the left?是否可以将分段控件标题的对齐方式设置为左侧?
【发布时间】:2019-09-23 22:08:41
【问题描述】:

我一直在寻找一种方法来设置分段控件标题向左对齐,但我似乎无法实现我想要的。

我创建了这个小函数来更改段控件的子视图的框架。 起初它有效。

    func modifyFrameOfSegment() {
       for segment in segmentedControl.subviews {
          guard segment.subviews.isNotEmpty else { return }
          segment.contentMode = .left
           for label in segment.subviews where label is UILabel {
              label.frame = CGRect(x: 0, y: label.frame.origin.y, width: label.frame.size.width, height: label.frame.size.height)
              (label as! UILabel).textAlignment = .left
           }
       }
    }

但每次我选择一个新段时,它都会重置所有子视图的框架并再次居中对齐所有标题。

有没有办法在分段控件中实现分段标题的永久左对齐?

任何提示或建议将不胜感激。

感谢您的宝贵时间。

【问题讨论】:

  • 嗨@Martin,请尝试在viewDidLayoutSubviews 中调用此函数。让我知道它是否有效。
  • 您也可以通过在 stackview 中获取按钮并将按钮标题设置为左侧来实现类似的功能,但完全取决于它是否符合您的要求。让我澄清一下您要实现的目标。
  • @VikashSinha:你好 Vikash 我已经试过了。正如我所说,它在分段控件第一次出现时起作用,但是当我第一次在分段控件中选择一个新段时,它再次将所有标题居中。我似乎找不到阻止这种情况发生的方法。

标签: ios swift swift4 uisegmentedcontrol


【解决方案1】:

让我们用这个方法

self.segmentedControl.setContentPositionAdjustment(UIOffset(horizontal: -20, vertical: 0), forSegmentType: .left, barMetrics: .default)

你可以做你想做的(当然,你可以根据需要改变水平和垂直值)。结果如下:

【讨论】:

  • 这不是我真正想要的。在这里,您只是更改标题的偏移量。如果所有段标题具有相同的偏移量,它可能会起作用,但事实并非如此。我正在寻找一种通用方法来左对齐所有标题。
  • 当我试图帮助您解决问题时,投反对票是不公平的
  • 我不是故意的 对此感到抱歉
  • @Jacob 永远不要假设你知道谁投了反对票。无论作者的意图有多好,对未达标的答案投反对票并没有什么不公平的。投票不是尝试的奖励;它们表明答案的有用性。在这种情况下,您答案中的图片显示了为什么您的解决方案不是 OP 要求的:第二项仍然居中。
【解决方案2】:

更新:

显然无法设置项目的对齐方式,但您可以通过使用setContentOffset(_ offset: CGSize, forSegmentAt segment: Int) 调整每个单独项目的位置来伪造它。这是一个笨拙的例子:

class LeftSegmentedControl: UISegmentedControl {

    var margin : CGFloat = 10

    override func layoutSubviews() {
        super.layoutSubviews()
        leftJustifyItems()
    }

    func leftJustifyItems() {
        let fontAttributes = titleTextAttributes(for: .normal)
        let segments = numberOfSegments - 1
        let controlWidth = frame.size.width
        let segmentWidth = controlWidth / CGFloat(numberOfSegments)
        for segment in 0...segments {
            let title = titleForSegment(at: segment)
            setWidth(segmentWidth, forSegmentAt: segment)
            if let t = title {
                let titleSize = t.size(withAttributes: fontAttributes)
                let offset = (segmentWidth - titleSize.width) / 2 - margin
                self.setContentOffset(CGSize(width: -offset, height: 0), forSegmentAt: segment)
            }
        }
    }
}

它是这样的:

有一些注意事项:

  • 此版本将所有段设置为等宽,这可能不是您想要的。

  • 我使用了 10 像素的固定左边距,因为您似乎不太可能想要改变它,但您显然可以更改它或使其成为可设置的属性。

  • 仅仅因为你可以这样做并不意味着你应该这样做。就我个人而言,我不认为它看起来很棒,而且它在可用性方面受到影响部门也。用户希望分段控制项居中,左对齐项目将使他们更难知道在哪里点击以点击该段。对于示例中标记为“3rd”的短项而言,这似乎尤其如此。这并不可怕,只是看起来有点奇怪。

原答案:

UIControl(其中 UISegmentedControl 是一个子类)有一个 contentHorizontalAlignment 属性,该属性应该告诉控件以某种方式对齐其内容,因此合乎逻辑的做法是将其设置为:

let segmented = UISegmentedControl(items: ["Yes", "No", "Maybe"])
segmented.frame = CGRect(x:75, y:250, width:250, height:35)
segmented.contentHorizontalAlignment = .left

但这不起作用——你仍然可以让标签居中。如果您有一个令人信服的左对齐片段用例,您应该将请求发送给 Apple。

解决此问题的一种方法是将标签呈现为图像,然后将图像用作段标签而不是纯字符串。从How to convert a UIView to an image 中的代码开始,您可以轻松地继承 UISegmentedControl 以从项目字符串创建图像。

【讨论】:

  • 我也试过这个解决方案。没有像你指出的那样工作。我可能会创建一个错误报告供 Apple 调查。还是谢谢
猜你喜欢
  • 1970-01-01
  • 2010-11-30
  • 2011-02-15
  • 2015-03-22
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多