iOS에서 긴 작업을 할 때 "오버레이"로드
긴 작업을 할 때 Swift IOS 애플리케이션에서 기계를로드하는 예는 무엇입니까? 원격 서버에서 데이터를로드하는 예입니다. 검색했지만 답변을 찾지 못했습니다.
업데이트 :
@Sebastian Dressler에게 감사드립니다. 이것은 간단한 방법입니다. 내 코드를 업데이트하면 멋지게 실행됩니다.
public class LoadingOverlay{
var overlayView = UIView()
var activityIndicator = UIActivityIndicatorView()
class var shared: LoadingOverlay {
struct Static {
static let instance: LoadingOverlay = LoadingOverlay()
}
return Static.instance
}
public func showOverlay(view: UIView) {
overlayView.frame = CGRectMake(0, 0, 80, 80)
overlayView.center = view.center
overlayView.backgroundColor = UIColor(hex: 0x444444, alpha: 0.7)
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = 10
activityIndicator.frame = CGRectMake(0, 0, 40, 40)
activityIndicator.activityIndicatorViewStyle = .WhiteLarge
activityIndicator.center = CGPointMake(overlayView.bounds.width / 2, overlayView.bounds.height / 2)
overlayView.addSubview(activityIndicator)
view.addSubview(overlayView)
activityIndicator.startAnimating()
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
overlayView.removeFromSuperview()
}
}
사용하자 :
LoadingOverlay.shared.showOverlay(self.view)
//To to long tasks
LoadingOverlay.shared.hideOverlayView()
위의 답변은 로딩 뷰를 추가하지만 화면의 클릭 이벤트를 차단하지 않고 나머지 화면에 대한 장비도 제공하지 않습니다. 다음과 같이 달성 할 수 있습니다.
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .Alert)
alert.view.tintColor = UIColor.blackColor()
let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(10, 5, 50, 50)) as UIActivityIndicatorView
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
presentViewController(alert, animated: true, completion: nil)
스위프트 3.0
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
Swift 4.0 이상
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = UIActivityIndicatorView.Style.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
다음과 같이 숨길 수 있습니다.
dismiss(animated: false, completion: nil)
조립보기를 직접 만들어 부모보기에 추가하고 작업이 완료되면 제거합니다 (예 : 추가).
var overlay : UIView? // This should be a class variable
[ ... ]
overlay = UIView(frame: view.frame)
overlay!.backgroundColor = UIColor.blackColor()
overlay!.alpha = 0.8
view.addSubview(overlay!)
제거 :
overlay?.removeFromSuperview()
배경 흐림 + 활동 표시기, Swift 5 예제
extension UIView {
func showBlurLoader() {
let blurLoader = BlurLoader(frame: frame)
self.addSubview(blurLoader)
}
func removeBluerLoader() {
if let blurLoader = subviews.first(where: { $0 is BlurLoader }) {
blurLoader.removeFromSuperview()
}
}
}
class BlurLoader: UIView {
var blurEffectView: UIVisualEffectView?
override init(frame: CGRect) {
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = frame
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.blurEffectView = blurEffectView
super.init(frame: frame)
addSubview(blurEffectView)
addLoader()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func addLoader() {
guard let blurEffectView = blurEffectView else { return }
let activityIndicator = UIActivityIndicatorView(style: .whiteLarge)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
blurEffectView.contentView.addSubview(activityIndicator)
activityIndicator.center = blurEffectView.contentView.center
activityIndicator.startAnimating()
}
}
저처럼 늦은 사람을 위해 @Sonrobby 코드를 약간 수정했습니다. 내가 이해했듯이 @Sonrobby는 모든 showOverlay
호출 의 기계에 활동을 추가합니다 . 그리고 일부 구성은 init 함수에 전달되어 showOverlay
메서드 의 배치 만 허용 됩니다.
또한 내 앱이 대부분 흰색이기 때문에 기기의 배경을 검정색으로 변경합니다.
다음은 코드입니다.
public class LoadingOverlay{
var overlayView : UIView!
var activityIndicator : UIActivityIndicatorView!
class var shared: LoadingOverlay {
struct Static {
static let instance: LoadingOverlay = LoadingOverlay()
}
return Static.instance
}
init(){
self.overlayView = UIView()
self.activityIndicator = UIActivityIndicatorView()
overlayView.frame = CGRectMake(0, 0, 80, 80)
overlayView.backgroundColor = UIColor(white: 0, alpha: 0.7)
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = 10
overlayView.layer.zPosition = 1
activityIndicator.frame = CGRectMake(0, 0, 40, 40)
activityIndicator.center = CGPointMake(overlayView.bounds.width / 2, overlayView.bounds.height / 2)
activityIndicator.activityIndicatorViewStyle = .WhiteLarge
overlayView.addSubview(activityIndicator)
}
public func showOverlay(view: UIView) {
overlayView.center = view.center
view.addSubview(overlayView)
activityIndicator.startAnimating()
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
overlayView.removeFromSuperview()
}
}
때때로 코드를 실행할 수 있습니다. 개인적으로 showOverlay가 제대로 호출되지 않는 경우가 있습니다. 씬에 들어 가려고했기 때문에 viewDidLoad 중에 즉시이 함수를 호출 때문입니다.
저와 강화 문제가 발생하면 코드에 대한 수정 사항과 제가 권장하는 접근 방식 변경이 있습니다.
FIX : 다음과 같이 dispatch_async 호출에 대한 클로저로 두 코드 블록을 배치합니다.
dispatch_async(dispatch_get_main_queue(),
{ //code });
접근 방식 : 코드를 호출 할 때 기본 큐에 dispatch_after 호출을 수행하여 호출을 몇 밀리 초만큼 지연 수정합니다.
추론? viewDidLoad 동안 UI에 너무 많은 작업을 요청하는 것입니다.
솔루션에 대한이 능력이 도움이됩니다.
-조엘 롱
XCode v6.3.2에서 작동하는 PS 솔루션
@sonrobby 답변 업데이트, 마스크 크기 조정을 완화 배경보기 및 방향 처리 추가 ...이 간단한 작업에 사용할 수 있습니다.
public class LoadingOverlay{
var overlayView = UIView()
var activityIndicator = UIActivityIndicatorView()
var bgView = UIView()
class var shared: LoadingOverlay {
struct Static {
static let instance: LoadingOverlay = LoadingOverlay()
}
return Static.instance
}
public func showOverlay(view: UIView) {
bgView.frame = view.frame
bgView.backgroundColor = UIColor.gray
bgView.addSubview(overlayView)
bgView.autoresizingMask = [.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin,.flexibleHeight, .flexibleWidth]
overlayView.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
overlayView.center = view.center
overlayView.autoresizingMask = [.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin]
overlayView.backgroundColor = UIColor.black
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = 10
activityIndicator.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
activityIndicator.activityIndicatorViewStyle = .whiteLarge
activityIndicator.center = CGPoint(x: overlayView.bounds.width / 2, y: overlayView.bounds.height / 2)
overlayView.addSubview(activityIndicator)
view.addSubview(bgView)
self.activityIndicator.startAnimating()
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
bgView.removeFromSuperview()
}
}
keywindow에 추가하면 탐색 및 탭 표시 줄을 넘어갈 수 있습니다.
LoadingOverlay.shared.showOverlay(view: UIApplication.shared.keyWindow!)
ATKit을 사용하십시오.
참조 : https://aurvan.github.io/atkit-ios-release/index.html
ATProgressOverlay 클래스 https://aurvan.github.io/atkit-ios-release/helpbook/Classes/ATProgressOverlay.html
암호 :
import ATKit
ATProgressOverlay.sharedInstance.show() // Does not show network activity indicator on status bar.
ATProgressOverlay.sharedInstance.show(isNetworkActivity: true) // Shows network activity indicator on status bar.
스크린 샷 :
스위프트 3.
아래 답변에서 @Lucho의 코드를 사용하는 기계 배경색을 지우고 스피너 색상을 추가했습니다.
public class LoadingOverlay {
var overlayView : UIView!
var activityIndicator : UIActivityIndicatorView!
class var shared: LoadingOverlay {
struct Static {
static let instance: LoadingOverlay = LoadingOverlay()
}
return Static.instance
}
init(){
self.overlayView = UIView()
self.activityIndicator = UIActivityIndicatorView()
overlayView.frame = CGRect(0, 0, 80, 80)
overlayView.backgroundColor = .clear
overlayView.clipsToBounds = true
overlayView.layer.cornerRadius = 10
overlayView.layer.zPosition = 1
activityIndicator.frame = CGRect(0, 0, 40, 40)
activityIndicator.center = CGPoint(overlayView.bounds.width / 2, overlayView.bounds.height / 2)
activityIndicator.activityIndicatorViewStyle = .whiteLarge
activityIndicator.color = .gray
overlayView.addSubview(activityIndicator)
}
public func showOverlay(view: UIView) {
overlayView.center = view.center
view.addSubview(overlayView)
activityIndicator.startAnimating()
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
overlayView.removeFromSuperview()
}
}
자신의 뷰 컨트롤러를 준비로 표시하기위한 프로토콜을 만들었습니다. 사용법은 매우 간단합니다.
class ViewController: UIViewController, OverlayHost {
@IBAction func showOverlayButtonPressed() {
showOverlay(type: YourOverlayViewController.self,
fromStoryboardWithName: "Main")
}
}
결과 :
소스 코드 : https://github.com/agordeev/OverlayViewController
관련 기사 : https://andreygordeev.com/2017/04/18/overlay-view-controller-protocols-swift/
참고 URL : https://stackoverflow.com/questions/27960556/loading-an-overlay-when-running-long-tasks-in-ios
'ProgramingTip' 카테고리의 다른 글
UISegmentedControl을 컨테이너보기에 프로그래밍 방식으로 추가하는 방법 (0) | 2020.12.02 |
---|---|
차이를 반환하는 2 개의 배열 비교 (0) | 2020.12.02 |
Linux에서 사용중인 메모리 프로세스의 양을 확인하는 방법은 무엇입니까? (0) | 2020.12.02 |
Windows 8/10에서 NetBeans IDE 확장 (0) | 2020.12.02 |
프로그래밍 방식으로 UICollectionViewCell 너비 및 높이를 설정하는 방법 (0) | 2020.12.02 |