mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2024-12-22 23:58:36 +01:00
Enable pull to refresh on timeline and change refresh indicator to better show when it is successfully pulled. Issue #1520
This commit is contained in:
parent
c3fbf88fbb
commit
e26a00ddfe
@ -227,6 +227,7 @@
|
||||
51CE1C0B23622007005548FC /* RefreshProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51CE1C0A23622006005548FC /* RefreshProgressView.swift */; };
|
||||
51CE1C712367721A005548FC /* testURLsOfCurrentArticle.applescript in Sources */ = {isa = PBXBuildFile; fileRef = 84F9EADB213660A100CF2DE4 /* testURLsOfCurrentArticle.applescript */; };
|
||||
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
|
||||
51D637C223BEEF8300A3BBCD /* AccountRefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D637C123BEEF8300A3BBCD /* AccountRefreshControl.swift */; };
|
||||
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */; };
|
||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; };
|
||||
51E36E71239D6610006F47A5 /* AddWebFeedSelectFolderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E36E70239D6610006F47A5 /* AddWebFeedSelectFolderTableViewCell.swift */; };
|
||||
@ -1348,6 +1349,7 @@
|
||||
51C452B72265178500C03939 /* styleSheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styleSheet.css; sourceTree = "<group>"; };
|
||||
51CE1C0823621EDA005548FC /* RefreshProgressView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RefreshProgressView.xib; sourceTree = "<group>"; };
|
||||
51CE1C0A23622006005548FC /* RefreshProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshProgressView.swift; sourceTree = "<group>"; };
|
||||
51D637C123BEEF8300A3BBCD /* AccountRefreshControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshControl.swift; sourceTree = "<group>"; };
|
||||
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineDataSource.swift; sourceTree = "<group>"; };
|
||||
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = "<group>"; };
|
||||
51E36E70239D6610006F47A5 /* AddWebFeedSelectFolderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedSelectFolderTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -1869,6 +1871,7 @@
|
||||
51C45245226506C800C03939 /* UIKit Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51D637C123BEEF8300A3BBCD /* AccountRefreshControl.swift */,
|
||||
51F85BFA2275D85000C787DC /* Array-Extensions.swift */,
|
||||
51F85BF42273625800C787DC /* Bundle-Extensions.swift */,
|
||||
51627A92238A3836007B3B4B /* CroppingPreviewParameters.swift */,
|
||||
@ -3907,6 +3910,7 @@
|
||||
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
|
||||
512AF9C2236ED52C0066F8BE /* ImageHeaderView.swift in Sources */,
|
||||
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */,
|
||||
51D637C223BEEF8300A3BBCD /* AccountRefreshControl.swift in Sources */,
|
||||
51C45290226509C100C03939 /* PseudoFeed.swift in Sources */,
|
||||
51C452A922650DC600C03939 /* ArticleRenderer.swift in Sources */,
|
||||
5115CAF42266301400B21BCE /* AddContainerViewController.swift in Sources */,
|
||||
|
@ -63,9 +63,8 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
|
||||
refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged)
|
||||
|
||||
refreshControl = AccountRefreshControl(errorHandler: ErrorHandler.present(self))
|
||||
|
||||
configureToolbar()
|
||||
becomeFirstResponder()
|
||||
|
||||
@ -436,12 +435,29 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
}
|
||||
|
||||
@objc func refreshAccounts(_ sender: Any) {
|
||||
refreshControl?.endRefreshing()
|
||||
guard let refreshControl = refreshControl else { return }
|
||||
|
||||
// This is a hack to make sure that an error dialog doesn't interfere with dismissing the refreshControl.
|
||||
// If the error dialog appears too closely to the call to endRefreshing, then the refreshControl never disappears.
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present(self))
|
||||
}
|
||||
|
||||
let checkImageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
|
||||
checkImageView.tintColor = .label
|
||||
checkImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
refreshControl.addSubview(checkImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
checkImageView.heightAnchor.constraint(equalToConstant: 35.0),
|
||||
checkImageView.widthAnchor.constraint(equalToConstant: 35.0),
|
||||
checkImageView.centerXAnchor.constraint(equalTo: refreshControl.centerXAnchor),
|
||||
checkImageView.centerYAnchor.constraint(equalTo: refreshControl.centerYAnchor)
|
||||
])
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.33) {
|
||||
refreshControl.endRefreshing()
|
||||
checkImageView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Keyboard shortcuts
|
||||
|
@ -50,6 +50,8 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
|
||||
|
||||
refreshControl = AccountRefreshControl(errorHandler: ErrorHandler.present(self))
|
||||
|
||||
// Setup the Search Controller
|
||||
searchController.delegate = self
|
||||
searchController.searchResultsUpdater = self
|
||||
|
51
iOS/UIKit Extensions/AccountRefreshControl.swift
Normal file
51
iOS/UIKit Extensions/AccountRefreshControl.swift
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// AccountRefreshControl.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 1/2/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
|
||||
class AccountRefreshControl: UIRefreshControl {
|
||||
|
||||
var errorHandler: ((Error) -> ())? = nil
|
||||
|
||||
init(errorHandler: @escaping (Error) -> ()) {
|
||||
super.init()
|
||||
self.errorHandler = errorHandler
|
||||
addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
@objc func refreshAccounts(_ sender: Any) {
|
||||
|
||||
let checkImageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
|
||||
checkImageView.tintColor = .label
|
||||
checkImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(checkImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
checkImageView.heightAnchor.constraint(equalToConstant: 35.0),
|
||||
checkImageView.widthAnchor.constraint(equalToConstant: 35.0),
|
||||
checkImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
checkImageView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
])
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.33) {
|
||||
self.endRefreshing()
|
||||
checkImageView.removeFromSuperview()
|
||||
|
||||
// This is a hack to make sure that an error dialog doesn't interfere with dismissing the refreshControl.
|
||||
// If the error dialog appears too closely to the call to endRefreshing, then the refreshControl never disappears.
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
AccountManager.shared.refreshAll(errorHandler: self.errorHandler!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user