Как управлять размером текста в управлении сегментами для разных устройств?

Я пытаюсь создать собственный элемент управления сегментом с помощью CollectionViewCell. Таким образом, я могу управлять размером текста элемента управления сегментом на разных устройствах. Но он не работает должным образом на всех устройствах. Я взял одну ячейку внутри представления коллекции и использовал метод делегата sizeForItemAt, чтобы одинаково установить ячейки. Там будет всего 3 ячейки. Это показано на изображении.

Это код для sizeForItemAt

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: (collectionView.frame.width / 3), height: 50.0)
}

Вот результат, который я получаю Как управлять размером текста в управлении сегментами для разных устройств?

Как управлять размером текста в управлении сегментами для разных устройств?

поэтому я пытаюсь найти решение, с помощью которого я могу управлять размером текста на всех устройствах, и все ячейки также могут иметь одинаковый интервал.

Размер вашего шрифта необходимо уменьшить на устройствах меньшего размера, чтобы он соответствовал меньшей доступной ширине.

Shawn Frank 22.03.2022 05:21

@ShawnFrank Вы говорите поставить условие if для проверки размера устройства, и в соответствии с этим мне нужно изменить размер шрифта.

MeetMistry15 22.03.2022 05:46

Я не придумал, как лучше всего это сделать, но да, вы можете начать с чего-то простого, и если это сработает, продолжайте оптимизировать свое решение по мере необходимости.

Shawn Frank 22.03.2022 05:47

@MeetMistry15 Вы можете сделать это на UISegmentedControl: stackoverflow.com/questions/39685523/…

koen 22.03.2022 14:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
4
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

lbl_name.adjustsFontSizeToFitWidth = true

попробуй это

UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).adjustsFontSizeToFitWidth = true 
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).minimumScaleFactor = 6.0

Разве тогда все 3 этикетки не будут иметь разные размеры?

Shawn Frank 22.03.2022 05:50

@Akila Я уже пробовал с lbl_name.adjustsFontSizeToFitWidth = true, но это не работает

MeetMistry15 22.03.2022 07:09

@ Anbu.Karthik Я не использовал сегментированное управление напрямую, я создал его с помощью Collectionview, так как хотел управлять размером шрифта.

MeetMistry15 22.03.2022 07:10

@MeetMistry15 — вы можете использовать это в любом месте вашего класса

Anbu.Karthik 22.03.2022 09:26
Ответ принят как подходящий

Ниже приведен один из способов, который я могу придумать, но ни в коем случае не единственный.

Во-первых, я начал с настройки представления коллекции с горизонтальной компоновкой потока.

// Flow layout configuration, mainly to figure out width of the cells
private func createLayout() -> UICollectionViewFlowLayout {
    
    let flowLayout = UICollectionViewFlowLayout()
    flowLayout.minimumLineSpacing = horizontalPadding
    flowLayout.minimumInteritemSpacing = 0
    flowLayout.scrollDirection = .horizontal
    
    // Calculate the available width to divide the segments evenly
    var availableWidth = UIScreen.main.bounds.width
    
    // There will always be segments - 1 gaps, for 3 segments, there will be
    // 2 gaps and for 4 segments there will be 3 gaps etc
    availableWidth -= horizontalPadding * CGFloat(segments.count - 1)
    
    let cellWidth = availableWidth / CGFloat(segments.count)
    
    flowLayout.itemSize = CGSize(width: cellWidth,
                                 height: collectionViewHeight)
    
    return flowLayout
}

Как только я это сделаю, я столкнусь с той же проблемой, что в зависимости от ширины экрана мой текст может быть обрезан.

UICollectionView UISegmentController UICollectionViewCell custom swift iOS

Итак, как только ширина каждого сегмента определена, мы должны вычислить максимальный размер шрифта, чтобы показать полный текст для самого длинного сегмента, и этот размер шрифта должен применяться ко всем.

В этом случае длинный сегмент равен Vibration Intensity с точки зрения длины строки.

// Flow layout configuration, mainly to figure out width of the cells
private func createLayout() -> UICollectionViewFlowLayout {
    
    let flowLayout = UICollectionViewFlowLayout()
    flowLayout.minimumLineSpacing = horizontalPadding
    flowLayout.minimumInteritemSpacing = 0
    flowLayout.scrollDirection = .horizontal
    flowLayout.sectionInset = UIEdgeInsets(top: 0,
                                           left: horizontalPadding,
                                           bottom: 0,
                                           right: horizontalPadding)
    
    // Calculate the available width to divide the segments evenly
    var availableWidth = UIScreen.main.bounds.width
    
    // There will always be segments - 1 gaps, for 3 segments, there will be
    // 2 gaps and for 4 segments there will be 3 gaps etc
    availableWidth -= horizontalPadding * CGFloat(segments.count - 1)
    
    // Remove the insets
    availableWidth -= flowLayout.sectionInset.left + flowLayout.sectionInset.right
    
    let cellWidth = availableWidth / CGFloat(segments.count)
    
    // Add this function
    calculateApproxFontSize(forWidth: cellWidth)
    
    flowLayout.itemSize = CGSize(width: cellWidth,
                                 height: collectionViewHeight)
    
    return flowLayout
}

private func calculateApproxFontSize(forWidth width: CGFloat) {
    
    // Get the longest segment by length
    if let longestSegmentTitle = segments.max(by: { $1.count > $0.count }) {
        
        let tempLabel = UILabel()
        tempLabel.numberOfLines = 1
        tempLabel.text = longestSegmentTitle
        tempLabel.sizeToFit()
        
        guard var currentFont = tempLabel.font else { return }
        
        var intrinsicSize
            = (longestSegmentTitle as NSString).size(withAttributes: [.font : currentFont])
        
        // Keep looping and reduce the font size till the text
        // fits into the label
        // This could be optimized further using binary search
        // However this should be ok for small strings
        while intrinsicSize.width > width
        {
            currentFont = currentFont.withSize(currentFont.pointSize - 1)
            tempLabel.font = currentFont
            
            intrinsicSize
                = (longestSegmentTitle as NSString).size(withAttributes: [.font : currentFont])
        }

        // Set the font of the current label
        // segmentFontSize is a global var in the VC
        segmentFontSize = currentFont.pointSize
    }
}

Затем установите segmentFontSize в cellForItemAt indexPath

func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionView
        .dequeueReusableCell(withReuseIdentifier: SegmentCell.reuseIdentifier,
                             for: indexPath) as! SegmentCell
    
    cell.backgroundColor = .orange
    cell.title.text = segments[indexPath.item]
    
    // Adjust the font
    cell.title.font = cell.title.font.withSize(segmentFontSize)
    
    return cell
}

Это даст вам что-то вроде этого:

Resize UILabel to fit frame rect in swift iOS using UICollectionView as UISegmentView

Если вам было трудно понять какую-то часть, вот ссылка на полный код: https://gist.github.com/shawn-frank/03bc06d13f90a54e23e9ea8c6f30a70e

Другие вопросы по теме