UIRefreshControl-UITableViewController가 UINavigationController 내에있을 때 beginRefreshing이 작동하지 않습니다.
내 UITableViewController (UINavigationController 내에 있음)에서 UIRefreshControl을 설정했으며 예상대로 작동합니다 (예 : 풀다운으로 올바른 이벤트 발생). 그러나 프로그래밍 beginRefreshing
방식으로 새로 고침 컨트롤 에서 인스턴스 메소드를 다음과 같이 호출하면 다음과 같습니다.
[self.refreshControl beginRefreshing];
아무 반응이 없습니다. 아래로 움직여서 스피너를 표시해야합니다. endRefreshing
내가 새로 고침 후 그를 호출 할 때 방법은 제대로 작동합니다.
이 동작으로 기본 프로토 타입 프로젝트를 작성했으며 UITableViewController가 애플리케이션 대리자의 루트 뷰 컨트롤러에 직접 추가되면 다음과 같이 올바르게 작동합니다.
self.viewController = tableViewController;
self.window.rootViewController = self.viewController;
그러나 tableViewController
UINavigationController에 먼저를 추가 한 다음 탐색 컨트롤러를로 추가 rootViewController
하면 beginRefreshing
메소드가 더 이상 작동하지 않습니다. 예 :
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;
내 느낌은 이것이 탐색 컨트롤러 내의 중첩 된 뷰 계층 구조와 관련이 있다는 것입니다.
감사
프로그래밍 방식으로 새로 고침을 시작하면 contentoffset을 변경하여 테이블보기를 직접 스크롤해야합니다.
[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
사용자가 테이블보기의 중간 / 하단에있을 때 새로 고침 컨트롤로 스크롤하는 것이 바람직하지 않을 수 있기 때문입니다.
@muhasturk의 스위프트 2.2 버전
self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)
간단히 말해서,이 휴대용을 유지하려면이 확장을 추가하십시오
UIRefreshControl + ProgramaticallyBeginRefresh.swift
extension UIRefreshControl {
func programaticallyBeginRefreshing(in tableView: UITableView) {
beginRefreshing()
let offsetPoint = CGPoint.init(x: 0, y: -frame.size.height)
tableView.setContentOffset(offsetPoint, animated: true)
}
}
UITableViewController는 iOS 7 이후에 automaticAdjustsScrollViewInsets 속성을 갖습니다. 테이블보기에는 이미 contentOffset이있을 수 있습니다 (보통 (0, -64)).
따라서 프로그래밍 방식으로 새로 고침을 시작한 후 refreshControl을 표시하는 올바른 방법은 기존 contentOffset에 refreshControl의 높이를 추가하는 것입니다.
[self.refreshControl beginRefreshing];
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
위에서 설명한 전략을 사용한 Swift 확장 기능은 다음과 같습니다.
extension UIRefreshControl {
func beginRefreshingManually() {
if let scrollView = superview as? UIScrollView {
scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: true)
}
beginRefreshing()
}
}
다른 답변들 중 어느 것도 나를 위해 일하지 않았습니다. 그것들은 스피너가 보이고 회전하도록하지만, 리프레쉬 액션 자체는 결코 일어나지 않을 것입니다. 이것은 작동합니다 :
id target = self;
SEL selector = @selector(example);
// Assuming at some point prior to triggering the refresh, you call the following line:
[self.refreshControl addTarget:target action:selector forControlEvents:UIControlEventValueChanged];
// This line makes the spinner start spinning
[self.refreshControl beginRefreshing];
// This line makes the spinner visible by pushing the table view/collection view down
[self.tableView setContentOffset:CGPointMake(0, -1.0f * self.refreshControl.frame.size.height) animated:YES];
// This line is what actually triggers the refresh action/selector
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];
이 예제는 테이블보기를 사용하지만 콜렉션보기 일 수도 있습니다.
이미 언급 된 접근법 :
[self.refreshControl beginRefreshing];
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
스피너를 볼 수 있습니다. 그러나 애니메이션되지 않습니다. 내가 변경 한 가지는이 두 가지 방법의 순서이며 모든 것이 작동했습니다.
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl beginRefreshing];
이 질문도 참조하십시오
UIRefreshControl not showing spiny when calling beginRefreshing and contentOffset is 0
It looks like a bug to me, because it only occures when the contentOffset property of the tableView is 0
I fixed that with the following code (method for the UITableViewController) :
- (void)beginRefreshingTableView {
[self.refreshControl beginRefreshing];
if (self.tableView.contentOffset.y == 0) {
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
} completion:^(BOOL finished){
}];
}
}
For Swift 4/4.1
A mix of existing answer do the job for me:
refreshControl.beginRefreshing()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
Hope this helps!
Here is Swift 3 extension that shows spinner as well as animate it.
import UIKit
extension UIRefreshControl {
func beginRefreshingWithAnimation() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
if let scrollView = self.superview as? UIScrollView {
scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - self.frame.height), animated: true)
}
self.beginRefreshing()
}
}
}
It's works perfect to me:
Swift 3:
self.tableView.setContentOffset(CGPoint(x: 0, y: -self.refreshControl!.frame.size.height - self.topLayoutGuide.length), animated: true)
In addition to @Dymitry Shevchenko solution.
I found nice workaround to this issue. You can create extension to UIRefreshControl
that overwrites method:
// Adds code forgotten by Apple, that changes content offset of parent scroll view (table view).
- (void)beginRefreshing
{
[super beginRefreshing];
if ([self.superview isKindOfClass:[UIScrollView class]]) {
UIScrollView *view = (UIScrollView *)self.superview;
[view setContentOffset:CGPointMake(0, view.contentOffset.y - self.frame.size.height) animated:YES];
}
}
You can use new class by setting custom class in Identity Inspector for refresh control in Interface Builder.
Fort Swift 2.2+
self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)
If you use Rxswift for swift 3.1, can use below:
func manualRefresh() {
if let refreshControl = self.tableView.refreshControl {
self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.height), animated: true)
self.tableView.refreshControl?.beginRefreshing()
self.tableView.refreshControl?.sendActions(for: .valueChanged)
}
}
This work for swift 3.1, iOS 10.
For Swift 5, for me the only thing missing was to call refreshControl.sendActions(.valueChanged)
. I made an extension to make it more cleaner.
extension UIRefreshControl {
func beginRefreshingManually() {
if let scrollView = superview as? UIScrollView {
scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: false)
}
beginRefreshing()
sendActions(for: .valueChanged)
}
}
I use the same technique for show user "data is update" visual sign. A result user bring app from background and feeds/lists will be update with UI like users pull tables to refresh himself. My version contain 3 things
1) Who send "wake up"
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationHaveToResetAllPages object:nil];
}
2) Observer in UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(forceUpdateData) name:kNotificationHaveToWakeUp:nil];
}
3)The protocol
#pragma mark - ForcedDataUpdateProtocol
- (void)forceUpdateData {
self.tableView.contentOffset = CGPointZero;
if (self.refreshControl) {
[self.refreshControl beginRefreshing];
[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:1];
}
}
'developer tip' 카테고리의 다른 글
Visual Studio에서 마지막 커서 위치로 다시 이동하는 방법은 무엇입니까? (0) | 2020.07.24 |
---|---|
Gulp 오류 : 'jshint / src / cli'모듈을 찾을 수 없습니다 (0) | 2020.07.24 |
문자열의 제로 패드 숫자 (0) | 2020.07.24 |
Visual Studio Code : 형식이 들여 쓰기 설정을 사용하지 않습니다 (0) | 2020.07.24 |
Java에서 구분 기호가없는 문자열로 긴 정수를 어떻게 포맷합니까? (0) | 2020.07.24 |