Search code examples
iosswiftframeuiprogressviewbackground-foreground

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 current video is ended and next start play, we should swap positions of `progressView` with next dot-view. For swap i just change frames
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
and the last one: this problem occurs only after first returns from background
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 call setNeedsDisplay()
  • 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.
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)

images shows how it looks before background and afterenter image description here


Solution

  • matt from comments suggested me use constraints instead of frames and yes, it helps and it works
    only thing i can say is dont forget call setNeedsLayout() after constraints update