Самый простой способ для меня:
from unittest import patch, Mock
def test():
datetime_mock = Mock(wraps=datetime)
datetime_mock.now = Mock(return_value=datetime(1999, 1, 1)
patch('target_module.datetime', new=datetime_mock).start()
ВНИМАНИЕ для этого решения: вся функциональность из datetime module
из target_module
перестанет работать.
Это поворачивается, там три вещи , который должен быть сделан.
В этом типичном примере, единица текста находится в табличном представлении, представлении стека или подобной конструкции, которая дает его зафиксированная ширина . В примере мы хотим дополнить 60,20,20,24.
Таким образом, мы берем "существующий" intrinsicContentSize и на самом деле добавляем 80 к высоте .
необходимо было буквально вычислить высоту "до сих пор" механизмом, и изменение то значение.
я нахожу это сбивающим с толку, но это - то, как это работает. Для меня Apple должна выставить вызов, названный чем-то вроде "предварительного расчета высоты".
, Во-вторых, мы должны на самом деле использовать вызов textRect#forBounds с нашим новым меньшим размером .
Так в textRect#forBounds мы первый делаем размер меньшим и затем вызов супер.
Только несколько ответов на этой странице, к которой близко подходят, работая: ранее мы использовали шаблон, данный @LE24. Однако это - точная проблема - необходимо корректироваться, размер сначала ЗАТЕМ звонят супер, в textRect#forBounds.
, Если Вы делаете это неправильный путь, это обычно работает, , но не делает для определенных определенных текстовых длин . Вот пример "неправильного выполнения супер сначала":
Уведомление эти 60,20,20,24 поля корректны, НО вычисление размера является на самом деле неправильным, потому что оно было сделано с "супер первым" шаблоном в textRect#forBounds.
Фиксированный:
Только теперь делает механизм textRect#forBounds, знают, как сделать вычисление правильно:
Наконец!
Снова, в этом примере UILabel используется в типичной ситуации, где ширина фиксируется. Таким образом в intrinsicContentSize мы должны "добавить" общую дополнительную высоту, которую мы хотим. (Вы не должны "добавлять" всегда к ширине, которая была бы бессмысленна, поскольку она фиксируется.)
Затем в textRect#forBounds Вы предложили границы "до сих пор" авторасположением, Вы вычитаете Ваши поля, и только затем вызов снова к механизму textRect#forBounds, то есть в супер, который даст Вам результат.
Наконец и просто в drawText Вы, конечно, тянете в том же самом меньшем поле.
Уф!
let UIEI = UIEdgeInsets(top: 60, left: 20, bottom: 20, right: 24)
override var intrinsicContentSize:CGSize {
numberOfLines = 0 // don't forget!
var s = super.intrinsicContentSize
s.height = s.height + 60.0 + 20.0
return s
}
override func drawText(in rect:CGRect) {
let r = rect.inset(by: UIEI)
super.drawText(in: r)
}
override func textRect(forBounds bounds:CGRect,
limitedToNumberOfLines n:Int) -> CGRect {
let b = bounds
let tr = b.inset(by: UIEI)
let ctr = super.textRect(forBounds: tr, limitedToNumberOfLines: 0)
return ctr
}
Еще раз. Обратите внимание, что ответы на этом и другом QA, которые "почти" корректны, страдают, проблема в первом изображении выше - "супер находится в неправильном месте" . Необходимо вызвать размер, больше в intrinsicContentSize, и затем в textRect#forBounds Вы должны сначала , уменьшают границы первого предложения и затем вызов супер.
, Это - секрет.
Примечание, что Вы не должны и не должны должны быть дополнительно звонить, делает недействительным, sizeThatFits, needsLayout или любой другой вызов принуждения. Правильное решение должно работать правильно в нормальном авторасположении, тянут цикл.