英文:
UIProgressView do not redraw his frame when app launch back from background
问题
I have view with UIProgressView
and 3 dot-view. It's like a page control. Each page - the video. progressView
displays progress of video playback.
Ok. I do not use constraints for left and right anchors because my progressView
should swap places with dot-view. For example, when the current video is ended and the next starts playing, we should swap positions of progressView
with the next dot-view. To swap, I just change frames.
The problem is that when I move the app to the background and then return, my progressView
loses its old frame. It attaches to the left side because .frame.minX
is 0.
And the last problem: this issue occurs only after the first return from the background.
What I tried to do:
- Save
progressView
frames before the app goes to the background and restore them when the app comes to the foreground:progressView.frame = progressViewOldFrames
and callsetNeedsDisplay()
. - Add a constraint to the leftAnchor with a constant (
frame.minX
) before going to the background and remove it after coming to the foreground. - Combine these two approaches.
So now it looks like:
func appWillMoveInBackground() {
progressBarXConstraint = progressBar.leftAnchor.constraint(equalTo: self.leftAnchor, constant: progressBar.frame.minX)
progressBarXConstraint?.isActive = true
progressBarFrame = progressBar.frame
}
func updateProgressWidth() {
progressBarXConstraint?.isActive = false
// Here, I use constraints because my width and height also change,
// and only constraints help me.
progressBar.widthAnchor.constraint(equalToConstant: 32).isActive = true
progressBar.heightAnchor.constraint(equalToConstant: 6).isActive = true
progressBar.frame = progressBarFrame
progressBar.setNeedsDisplay()
}
UPDATE:
Okay, I should explain more. I guess I can't use constraints because there is some animation while scrolling. When we scroll to the right, we should move our progressView
to some points on the right. And at that moment, we should move the right dot-view to the left. I mean, we do not scroll page by page; we can scroll to halfway on the right, then we can return to the initial position.
This code block changes the frames of progressView
and dot-view. The exact formulas are not important. Please try to understand the behavior of this view:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Calculate some mathematical variables
// and call a method that makes changes in frames
pageControl.moveBetweenPages(atPercentValue: distInPercents - 100)
}
// It's part of the body of the moveBetweenPages() function
progressBar.frame = CGRect(x: progStartX + progAddDist, y: 0,
width: SizeConstants.progressBarWidth.value,
height: SizeConstants.height.value)
let dotStartX: CGFloat = SizeConstants.progressBarWidth.value + SizeConstants.itemsSpacing.value + (CGFloat(currentPageNum) * dotSectionSize)
dots[currentPageNum].view.frame = CGRect(x: dotStartX - dotAddDist, y: 0,
width: SizeConstants.dotWidth.value,
height: SizeConstants.height.value)
Images show how it looks before going to the background and after:
英文:
<br>
i have view with UIProgressView
and 3 dot-view. It's like a page control. Each page - the video. progressView
displays progress of video playback
<br>
ok. I do not use constraints for left and right anchors, because my progressView should swap places with dot-view. For example, when current video is ended and next start play, we should swap positions of progressView
with next dot-view. For swap i just change frames
<br>
and the problem is: when i move app to background and returns back, my progressView
loses his old frame. It attaches to the left side, because .frame.minX
is 0
<br>
and the last one: this problem occurs only after first returns from background
<br>
what i tried to do:
- save
progressView
frames before app is going to background and restore it when app comes to foreground:progressView.frame = progressViewOldFrames
and callsetNeedsDisplay()
- add constraint to leftAnchor with constant (
frame.minX
) before background and remove it after foreground - combine these 2 tries
so now it looks like
func appWillMoveInBackground() {
progressBarXConstraint = progressBar.leftAnchor.constraint(equalTo: self.leftAnchor, constant: progressBar.frame.minX)
progressBarXConstraint?.isActive = true
progressBarFrame = progressBar.frame
}
func updateProgressWidth() {
progressBarXConstraint?.isActive = false
// here i use constraints because my width and height also disables
// and only constraints helps me
progressBar.widthAnchor.constraint(equalToConstant: 32).isActive = true
progressBar.heightAnchor.constraint(equalToConstant: 6).isActive = true
progressBar.frame = progressBarFrame
progressBar.setNeedsDisplay()
}
UPDATE
ok, i should explain more. I guess i cant use constraints because we have some animation while we are scrolling. When we scroll to right - we should move our progressView
to some points at right. And in this moment we should move right dot-view to the left. I mean, we do not scroll page by page, we can scroll to a half on the right, then we can return to the initial position.
<br>
this code of block did change frames of progressView and dot-view. Formulas are not important. Please, just understand the behavior of this view
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// calc some math variables
// and call method that make changes in frames
pageControl.moveBetweenPages(atPercentValue: distInPercents - 100)
}
// its part of body moveBetweenPages() func
progressBar.frame = CGRect(x: progStartX + progAddDist, y: 0,
width: SizeConstants.progressBarWidth.value,
height: SizeConstants.height.value)
let dotStartX: CGFloat = SizeConstants.progressBarWidth.value + SizeConstants.itemsSpacing.value + (CGFloat(currentPageNum) * dotSectionSize)
dots[currentPageNum].view.frame = CGRect(x: dotStartX - dotAddDist, y: 0,
width: SizeConstants.dotWidth.value,
height: SizeConstants.height.value)
答案1
得分: 0
matt在评论中建议我使用constraints
而不是frames
,是的,这有帮助,而且有效。
唯一需要注意的是,在更新约束后不要忘记调用setNeedsLayout()
。
英文:
matt from comments suggested me use constraints
instead of frames and yes, it helps and it works
<br>
only thing i can say is dont forget call setNeedsLayout()
after constraints update
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论