简体   繁体   English

是否可以将分段控制标题的 alignment 设置在左侧?

[英]Is it possible to set the alignment of segmented Control titles to the left?

I have been looking around for a way to set the alignment of the segmented control titles to the left but I don't seem to be able to achieve what I want.我一直在寻找一种将分段控件标题的 alignment 设置到左侧的方法,但我似乎无法实现我想要的。

I have created this little function to change the frame of the subviews of the segment control.我创建了这个小 function 来更改段控件的子视图的框架。 It works at first.它起初有效。

    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
           }
       }
    }

But everytime I select a new segment it resets the frames of all the subviews and center align all the titles again.但是每次我 select 一个新段时,它都会重置所有子视图的框架并再次居中对齐所有标题。

Is there a way to achieve a permanent left alignment for the segment titles in a segmented control?有没有办法为分段控件中的分段标题实现永久左 alignment?

Any tips or advice would be greatly appreciated.任何提示或建议将不胜感激。

Thank you for your time.感谢您的时间。

Let's use this method让我们使用这个方法

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

And you can do what you want (Of course, you can change the horizontal & vertical value by your needs).你可以做你想做的(当然,你可以根据需要改变水平和垂直值)。 Here is the result:结果如下:

在此处输入图像描述

Update:更新:

There's apparently no way to set the alignment of the items, but you can fake it by adjusting the position of each individual item using setContentOffset(_ offset: CGSize, forSegmentAt segment: Int) .显然没有办法设置项目的 alignment,但您可以通过使用setContentOffset(_ offset: CGSize, forSegmentAt segment: Int)调整每个单独项目的 position 来伪造它。 Here's a kludgy example:这是一个笨拙的例子:

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)
            }
        }
    }
}

Here's what it looks like:这是它的样子:

There are a few caveats:有几个注意事项:

  • This version sets the segments to all have equal width, which might not be what you want.此版本将所有段设置为具有相等的宽度,这可能不是您想要的。

  • I used a fixed left margin of 10px because it seems unlikely that you'd want to vary that, but you can obviously change it or make it a settable property.我使用了 10px 的固定左边距,因为您似乎不太可能想要改变它,但您显然可以更改它或使其成为可设置的属性。

  • Just because you can do this doesn't mean you should.仅仅因为你做到这一点并不意味着你应该这样做。 Personally, I don't think it looks great, and it suffers in the usability department too.就个人而言,我不认为它看起来很棒,而且它在可用性部门也受到影响。 Users expect segmented control items to be centered, and left-justifying the items will make it harder for them to know where to tap to hit the segment.用户希望分段控制项居中,左对齐项目将使他们更难知道在哪里点击以点击该段。 That seems particularly true for short items like the one labelled "3rd" in the example.对于示例中标记为“3rd”的短项而言,这似乎尤其如此。 It's not terrible, it just seems a little weird.这并不可怕,只是看起来有点奇怪。

Original answer:原答案:

UIControl (of which UISegmentedControl is a subclass) has a contentHorizontalAlignment property that's supposed to tell the control to align its content a certain way, so the logical thing to do would be to set it like this: UIControl(其中 UISegmentedControl 是一个子类)有一个contentHorizontalAlignment属性,该属性应该告诉控件以某种方式对齐其内容,因此合乎逻辑的做法是将其设置为:

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

But that doesn't work — you still get the labels centered.但这不起作用——你仍然让标签居中。 If you've got a compelling use case for left-aligned segments, you should send the request to Apple.如果您有一个令人信服的左对齐片段用例,您应该将请求发送给 Apple。

One way you could work around this problem is to render your labels into images and then use the images as the segment labels instead of plain strings.解决此问题的一种方法是将标签呈现为图像,然后将图像用作段标签而不是纯字符串。 Starting from the code in How to convert a UIView to an image , you could easily subclass UISegmentedControl to create images from the item strings.如何将 UIView 转换为图像中的代码开始,您可以轻松地继承 UISegmentedControl 以从项目字符串创建图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM