Доброго времени всем.
Появился такой вопрос, у меня есть допустим одинаковые UILabel
в проекте, и я хочу сделать один общий класс для UILabel
и потом наследовать его другими.
Правильный ли это подход?
Просто никогда не видел чтобы кто то создавал отдельный класс для каждого элемента и задавал ему шрифт и размер, в основном всё делают в IB
.
Как правильно делать верстку для приложения?
Все правильно вы думаете. Так делают и это правильно.
Это очень нужно для создания своих стилей каждому элементу. В будущем таким образом менять или править что-то проще в одном своем классе.
То есть условно говоря мне нужно делать так.
Создать класс от UILabel
.
class customLabel : UILabel {
// тут код
}
Потом в IB
унаследовать этот класс?
Именно так…
Для большей гибкости, можно создать для каждого элемента общий класс, с общими настройками
class StyledLabel: UILabel {}
В нем можно делать общие настройки для всех лейблов.
Дальше можно уже создавать конкретные классыы под каждый стиль
class BodyPrimaryLabel: StyledLabel {
// тут указывать уже конкретные стили, фонт, цвет, фон и т.д.
}
class BodySecondaryLabel: StyledLabel {
// тут указывать уже конкретные стили, фонт, цвет, фон и т.д.
}
И так далее. Для любого элемента.
Так же советую вынести отдельно цвета, размер текста. Из этого скомпоновать фонт. Т.е. у вас получится полноценный конструктор.
В конце вам нужно будет лишь указать для элемента нужный класс и задать текст.
Все изменения будут в одном месте. Понадобилось для Primary стиля увеличить размер текста, легко. Поменять цвет текста для заголовков, легко.
А не проще сделать стиль и скармливать его как зависимость, зачем столько наследников?
вот что я имею ввиду
protocol TextStyleType {
var font: UIFont { get }
var textColor: UIColor { get }
var textAlignment: NSTextAlignment { get }
}
protocol TextStyleApplicable {
func applyStyle(_ style: TextStyleType)
}
extension UILabel: TextStyleApplicable {
func applyStyle(_ style: TextStyleType) {
self.font = font
self.textColor = style.textColor
self.textAlignment = style.textAlignment
}
}
extension UITextField: TextStyleApplicable {
func applyStyle(_ style: TextStyleType) {
self.font = font
self.textColor = style.textColor
self.textAlignment = style.textAlignment
}
}
extension UITextView: TextStyleApplicable {
func applyStyle(_ style: TextStyleType) {
self.font = font
self.textColor = style.textColor
self.textAlignment = style.textAlignment
}
}
struct ConcreteTextStyle: TextStyleType {
var font: UIFont
var textColor: UIColor
var textAlignment: NSTextAlignment
}
enum TextStyleFactory {
// MARK: - Main header style
static let mainHeaderTextStyle = ConcreteTextStyle(
font: .systemFont(ofSize: 30),
textColor: .blue,
textAlignment: .center
)
static let mainHeaderTextStyleLeft = mainHeaderTextStyle.byAdding(.textAlignment(.left))
// MARK: - Message text style
static let messageTextStyle = ConcreteTextStyle(
font: .systemFont(ofSize: 18),
textColor: .blue,
textAlignment: .center
)
static let messageTextStyleLeft = messageTextStyle.byAdding(.textAlignment(.left))
static let messageTextStyleRight = messageTextStyle.byAdding(.textAlignment(.right))
}
let field = UITextField()
let label = UITextField()
let textView = UITextField()
field.applyStyle(TextStyleFactory.mainHeaderTextStyle)
label.applyStyle(TextStyleFactory.messageTextStyle)
textView.applyStyle(TextStyleFactory.messageTextStyleLeft)
На самом деле все так и есть, в простом варианте. Хотя у вас вышло чересчур сложно.
Но если нужно делать более гибкую систему стилей, с поддержкой разных фич, там уже будет кода и логики больше. Как говорится “на вкус и цвет…”.
Я делал кастомные классы под каждый элемент вью, а уже от них создавал конкретные классы со стилями. Это мне показалось логичным. Так я мог в базовом классе делать определенные манипуляции со стилями, если нужно было. Так же создавал различные модификаторы и прочее.
Позже напарник решил сделать свою версию стилей и он отказался от кастомных классов. У него было похожее на ваш случай. Каждый разработчик хочет сделать по своему, что бы было проще(на его взгляд), но кому-то это будет казаться не таким простым. Поэтому от сюда и возникает множество решений, изучив которые, можно принять заключение и использовать то что нравится, либо пробовать сделать по своему, что покажется проще. Замкнутый круг
Добрый день уважаемые форумчане! Что бы разобраться в этом вопросе необходимо вспомнить какой язык понимает процессор вашего телефона. Он понимает язык машинных кодов. Первоначально писали на них. Потом создавались языки программирования все более и более высоких уровней. И наконец появился SWIFT! Встает вопрос, а почему обобщение которое мы обсуждаем не предусмотрено в компиляторе? Ответ по моему очевиден. Это сделало SWIFT менее гибким и более сложным. Т.е. в компиляторе предусмотрена золотая середина обобщенности языка. Далее вопрос: " А если в моем приложении можно сделать более высокий уровень обобщенности, то мне это делать?" Ответ да делать, но только в вашем приложении. В других это может мешать.