- Если я рисую диаграмму внутри
- (void)drawRect:(CGRect)rect
, достаточно установить [_chartView setContentMode:UIViewContentModeRedraw]
, и этот метод будет вызываться, когда устройство изменит его ориентацию, и можно вычислить f.e. новый центр для моей диаграммы. - Если я создаю представление, подобное subview, используя
- (id)initWithFrame:(CGRect)frame
, а затем добавьте его в контроллер вида, например[self.view addSubview:chartView];
. Как в этом случае я могу обрабатывать поворот, чтобы перерисовать диаграмму?
Перерисовка пользовательского интерфейса при изменении ориентации устройства
Ответ 1
Чтобы ваша диаграмма была правильно отображена при изменении ориентации устройства, вам необходимо обновить схему диаграммы, вот код, который вы должны добавить в свой контроллер:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_chartView.frame = self.view.bounds;
[_chartView strokeChart];
}
Ответ 2
Использование .Redraw
Программный вызов myView.contentMode = .Redraw
при создании пользовательского представления должен быть достаточным. Это единственный флаг в IB и, как таковой, предпочтительнее 0 строк кода. См. "Переполнение стека Как вызвать drawRect в подклассе UIView.
Использование setNeedsDisplay()
Если вы должны вызвать перерисовку, сделайте это в setNeedsDisplay
, которая, в свою очередь, вызовет drawRect
.
Нет необходимости слушать уведомления и рефакторировать код.
Swift
override func layoutSubviews() {
super.layoutSubviews()
self.setNeedsDisplay()
}
Objective-C
- (void)layoutSubviews {
[super layoutSubviews];
[self setNeedsDisplay];
}
Примечание: layoutSubviews
- это метод UIView
, не a UIViewController
.
Ответ 3
Go здесь, чтобы узнать, как получать уведомления, когда меняется ориентация устройства. Когда ориентация изменится, просто вызовите [chartView setNeedsDisplay];
, чтобы вызвать drawRect:
, чтобы вы могли обновить свое представление. Надеюсь, это поможет!
Ответ 4
Код, который вы добавите в контроллер вида:
- (void)updateViewConstraints
{
[super updateViewConstraints];
[_chartView setNeedsDisplay];
}
Ответ 5
Спасибо Keenle за вышеупомянутое решение ObjC. Я возился с созданием запрограммированных ограничений все утро, убивая свой мозг, не понимая, почему они не будут перекомпилировать/перестроить представление. Думаю, потому, что я создал UIView программно, используя CGRect... это имело приоритет.
Однако, вот мое решение было быстрым:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myUIView.center = CGPoint(x: (UIScreen.mainScreen().bounds.width / 2), y: (UIScreen.mainScreen().bounds.height / 2))
}
Так с облегчением!:)
Ответ 6
К сожалению, некоторые ответы предлагают переопределить методы контроллера, но у меня есть пользовательский UITableViewCells
с теневым окружением и поворот устройства растягивает ячейки, но не перерисовывает тень. Поэтому я не хочу, чтобы мой код в контроллере (re) рисовал subview.
Решением для меня является прослушивание уведомления UIDeviceOrientationDidChange
в моем пользовательском UITableViewCell
, а затем вызов setNeedsDisplay()
, как было предложено.
Пример кода Swift 4.0 в одном из моих пользовательских UITableViewCells
override func awakeFromNib() {
super.awakeFromNib()
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChangeNotification), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
@objc func deviceOrientationDidChangeNotification(_ notification: Any) {
Logger.info("Orientation changed: \(notification)")
setNeedsLayout()
}
BTW: Logger
- от typealias
до SwiftyBeaver
.
Благодаря @Aderis указывая мне в правильном направлении.