Я пытаюсь создать собственный элемент управления сегментом с помощью 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)
}
Вот результат, который я получаю


поэтому я пытаюсь найти решение, с помощью которого я могу управлять размером текста на всех устройствах, и все ячейки также могут иметь одинаковый интервал.
@ShawnFrank Вы говорите поставить условие if для проверки размера устройства, и в соответствии с этим мне нужно изменить размер шрифта.
Я не придумал, как лучше всего это сделать, но да, вы можете начать с чего-то простого, и если это сработает, продолжайте оптимизировать свое решение по мере необходимости.
@MeetMistry15 Вы можете сделать это на UISegmentedControl: stackoverflow.com/questions/39685523/…





lbl_name.adjustsFontSizeToFitWidth = true
попробуй это
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).adjustsFontSizeToFitWidth = true
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).minimumScaleFactor = 6.0
Разве тогда все 3 этикетки не будут иметь разные размеры?
@Akila Я уже пробовал с lbl_name.adjustsFontSizeToFitWidth = true, но это не работает
@ Anbu.Karthik Я не использовал сегментированное управление напрямую, я создал его с помощью Collectionview, так как хотел управлять размером шрифта.
@MeetMistry15 — вы можете использовать это в любом месте вашего класса
Ниже приведен один из способов, который я могу придумать, но ни в коем случае не единственный.
Во-первых, я начал с настройки представления коллекции с горизонтальной компоновкой потока.
// 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
}
Как только я это сделаю, я столкнусь с той же проблемой, что в зависимости от ширины экрана мой текст может быть обрезан.
Итак, как только ширина каждого сегмента определена, мы должны вычислить максимальный размер шрифта, чтобы показать полный текст для самого длинного сегмента, и этот размер шрифта должен применяться ко всем.
В этом случае длинный сегмент равен 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
}
Это даст вам что-то вроде этого:
Если вам было трудно понять какую-то часть, вот ссылка на полный код: https://gist.github.com/shawn-frank/03bc06d13f90a54e23e9ea8c6f30a70e
Размер вашего шрифта необходимо уменьшить на устройствах меньшего размера, чтобы он соответствовал меньшей доступной ширине.