【问题标题】:Locking scrollview while refreshing?刷新时锁定滚动视图?
【发布时间】:2019-04-05 22:18:53
【问题描述】:

我正在开发一个应用程序,并希望我的滚动视图在数据加载时锁定到位。目前,当用户刷新滚动视图时,它会立即恢复原位。如何调整我的代码以使滚动视图锁定到位,直到其中的代码完全执行?到目前为止,这是我的代码:

@IBOutlet weak var scrollView: UIScrollView!
var refreshControl: UIRefreshControl!

@objc func refreshData(sender: UIRefreshControl){
    getItems()
  
    sender.endRefreshing()
}

这是我的 getItems() 函数:

   func getItems() {
    //Hit the web service Url
    let serviceUrl = "omitted"
    let url = URL(string: serviceUrl)
    //Download the json data
    if let url = url{
        //Create a URL Session
        let session = URLSession(configuration: .default)
        let request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 15.0)
        let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
            if error == nil {
                //Succeeded
                //Call the parse json function on the data
                self.parseJson(data!)
            }
            else {
                print("error occured in getItems")
            }
        })
        // Start the task
        task.resume()
    }
}
//Parse it out into DataModel structs

func parseJson(_ data:Data){
    //parse the data into DataModel structs
    do{
        //parse the data into a json object
        let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as! [Any]
        //loop through each result in the json array
        for jsonResult in jsonArray {
            //Cast json result as a dictionary
            let jsonDict = jsonResult as! [String:String]
            //create new bar data and set its properties
            let bardata = DataModel(name: jsonDict["Bar Name"]!, cover: jsonDict["Bar Cover"]!, deals: jsonDict["Drink Deals"]!)
            //add it to the array
            bar_info.append(bardata)
        }
    }
    catch{
        print("There was an error")
    }
    //call function here
    update_cover()
    
}

func update_cover(){
    var a_cover = "$5"
    var b_cover = "$5"
    var c_cover = "$5"
    var d_cover = "$5"
    
    for item in bar_info{
        if item.name == "omitted"{
            a = item.cover
        }
        
        else if item.name == "omitted"{
            b_cover = item.cover
        }
            
        else if item.name == "omitted"{
            c_cover = item.cover
        }
    
        else if item.name == "omitted"{
            d_cover = item.cover
        }
    }
    
    
    DispatchQueue.main.async {
        self.aCoverView.text = a_cover
        self.bCoverView.text = b_cover
        self.cCoverView.text = c_cover
       self.dCoverView.text = d_cover
    }
}

【问题讨论】:

  • 是否需要阻止用户交互,或者让滚动视图返回到重新加载数据之前的位置?
  • 我需要滚动视图保持原位,同时刷新控件执行其中的功能。如果你熟悉的话,有点像 Instagram 或 facebook 的作品。
  • getItems() 是否进行一些异步操作,例如通过网络刷新数据?在这种情况下,它将在请求完成之前立即返回。如果是这种情况,刷新控件应该在网络请求的完成处理程序中结束刷新。
  • 你能添加你的getItems()方法代码吗?
  • @DionizB 我已经更新了我的代码,以便它显示 getItems() 方法

标签: ios swift uiscrollview uirefreshcontrol


【解决方案1】:

听起来您正在实现 pull-to-refresh,所以我假设您会想要使用 scrollViewDidScroll 委托方法:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    let offset = scrollView.contentOffset // get the current offset
    scrollView.isUserInteractionEnabled = false // disable interaction
    scrollView.setContentOffset(offset, animated: false) // freeze the offset

}

现在你只需要配置方法。

【讨论】:

    【解决方案2】:

    你可以在getItems做这样的事情:

        func getItems() {
            //Hit the web service Url
            let serviceUrl = "omitted"
            let url = URL(string: serviceUrl)
            //Download the json data
            if let url = url{
                //Create a URL Session
                let session = URLSession(configuration: .default)
                let request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 15.0)
                let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
                    DispatchQueue.main.async {
                        self.refreshControl.endRefreshing()
                    }
                    if error == nil {
                        //Succeeded
                        //Call the parse json function on the data
                        self.parseJson(data!)
                    }
                    else {
                        print("error occured in getItems")
                    }
                })
                // Start the task
                task.resume()
            }
        }
    

    只有在网络请求完成后(即在完成处理程序中),刷新控件才需要结束刷新。由于请求是异步的,getItems 在请求仍在进行时立即返回。

    【讨论】:

      【解决方案3】:

      在重新加载滚动视图之前,存储当前位置的内容偏移量,然后在重新加载完成时设置它。

      var currentPos:CGPoint?
      
      func reloadScrollview() { 
          currentPos = scrollview.contentOffset
      
          // do your reloading stuff
          // layout your subviews inside the scrollview
          // set the content size based upon your subviews
      
          scrollview.contentOffset = currentPos
      
      }
      

      【讨论】:

        【解决方案4】:

        要锁定滚动视图,请使用:

        scrollView.isUserInteractionEnabled = false
        

        然后解锁:

        scrollView.isUserInteractionEnabled = true
        

        【讨论】:

          猜你喜欢
          • 2020-01-31
          • 1970-01-01
          • 1970-01-01
          • 2013-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多