- (void)drawRect:(CGRect)rect
内にグラフを描画すると、[__chartView setContentMode:UIViewContentModeRedraw]
_を設定するのに十分であり、デバイスが方向を変更したときにこのメソッドが呼び出され、f.eを計算することができます。チャートの新しい中心点。- (id)initWithFrame:(CGRect)frame
を使用してサブビューのようなビューを作成し、それを_[self.view addSubview:chartView];
_のようなビューコントローラーに追加した場合。この場合、回転を処理してチャートを再描画するにはどうすればよいですか?デバイスの向きが変わったときにチャートを正しくレンダリングするには、チャートのレイアウトを更新する必要があります。ViewControllerに追加する必要があるコードは次のとおりです。
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_chartView.frame = self.view.bounds;
[_chartView strokeChart];
}
_.Redraw
_の使用
カスタムビューの作成時にプログラムで_myView.contentMode = .Redraw
_を呼び出すだけで十分です。 [〜#〜] ib [〜#〜]の単一フラグであり、そのため、 0行のコードが望ましい方法です。 Stack Overflow IViewサブクラスでdrawRectをトリガーする方法 を参照してください。
setNeedsDisplay()
の使用
再描画をトリガーする必要がある場合は、setNeedsDisplay
でトリガーし、drawRect
を呼び出します。
通知を聞いたり、コードをリファクタリングする必要はありません。
Swift
_override func layoutSubviews() {
super.layoutSubviews()
self.setNeedsDisplay()
}
_
Objective-C
_- (void)layoutSubviews {
[super layoutSubviews];
[self setNeedsDisplay];
}
_
注:layoutSubviews
はUIView
メソッド、nota UIViewController
メソッド。
here に進み、デバイスの向きが変わったときに通知を受け取る方法を学習します。向きが変わったら、[chartView setNeedsDisplay];
作る drawRect:
が呼び出され、ビューを更新できるようになります。お役に立てれば!
View Controllerに追加するコード:
- (void)updateViewConstraints
{
[super updateViewConstraints];
[_chartView setNeedsDisplay];
}
残念ながら、いくつかの答えはコントローラーメソッドをオーバーライドすることを示唆していますが、いくつかのカスタムUITableViewCells
の周りに影があり、デバイスを回転させるとセルが引き伸ばされますが、影は再描画されません。したがって、サブビューを(再)描画するためにコントローラー内にコードを配置したくありません。私にとっての解決策は、カスタムUIDeviceOrientationDidChange
内でUITableViewCell
通知をリッスンし、提案どおりsetNeedsDisplay()
を呼び出すことです。
カスタムUITableViewCellsのいずれかのSwift 4.0コード例
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()
}
ところで:Logger
はtypealias
からSwiftyBeaver
です。 @Aderisが私を正しい方向に向けてくれてありがとう。
「setNeedsDisplay」をさまざまな方法で試してみましたが、アニメーション化するビューの影を新しい位置に調整するために機能しませんでした。
私はこれで私の問題を解決しました。シャドウが協力/更新したくない場合は、シャドウをnilに設定してから再度設定してみてください。
UIView.animateKeyframes(withDuration: 0.2 /*Total*/, delay: 0.0, options: UIViewKeyframeAnimationOptions(), animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 10/10, animations:{
// Other things to animate
//Set shadow to nil
self.viewWithShadow.layer.shadowPath = nil
})
}, completion: { finished in
if (!finished) { return }
// When the view is moved, set the shadow again
self.viewWithShadow.layer.shadowPath = UIBezierPath(rect: self.descTextView.bounds).cgPath
})
まだ影がなく、そのコードが必要な場合は、次のとおりです。
func addShadowTo (view: UIView) {
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.gray.cgColor
view.layer.shadowOffset = CGSize( width: 1.0, height: 1.0)
view.layer.shadowOpacity = 0.5
view.layer.shadowRadius = 6.0
view.layer.shadowPath = UIBezierPath(rect: view.bounds).cgPath
view.layer.shouldRasterize = true
}
上記のObjCソリューションをありがとう、Keenle。プログラムされた制約を午前中に作成し、脳を殺し、なぜそれらがビューを再コンパイル/再配置しないのか理解できずにいじっていました。私は、CGRectを使用してプログラムでUIViewを作成したためだと思います...これが優先されていました。
ただし、Swiftでの私のソリューションは次のとおりです。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myUIView.center = CGPoint(x: (UIScreen.mainScreen().bounds.width / 2), y: (UIScreen.mainScreen().bounds.height / 2))
}
ほっとした! :)