При отключении отскоков в UIPageViewController прокрутка не будет работать вообще [дубликат]

Невозможность связывания с соответствующими библиотеками / объектными файлами или компиляция файлов реализации

Обычно каждая единица перевода генерирует объектный файл, содержащий определения символов, определенных в этой единицы перевода. Чтобы использовать эти символы, вам необходимо связать эти объектные файлы.

В разделе gcc вы должны указать все объектные файлы, которые должны быть связаны вместе в командной строке, или скомпилировать файлы реализации вместе.

g++ -o test objectFile1.o objectFile2.o -lLibraryName

Здесь libraryName - это просто имя библиотеки, без добавления к платформе. Так, например, в файлах библиотеки Linux обычно называют libfoo.so, но вы должны писать только -lfoo. В Windows этот же файл можно назвать foo.lib, но вы будете использовать тот же аргумент. Возможно, вам придется добавить каталог, в котором эти файлы можно найти, используя -L‹directory›. Обязательно не записывайте пробел после -l или -L.

Для XCode: добавьте пути поиска заголовка пользователя -> добавьте путь поиска библиотеки -> перетащите фактическую ссылку библиотеки в

В MSVS файлы, добавленные в проект, автоматически связывают их объектные файлы, и будет создан файл lib (в общем использовании). Чтобы использовать символы в отдельном проекте, вам нужно будет добавить файлы lib в параметры проекта. Это делается в разделе Linker свойств проекта в Input -> Additional Dependencies. (путь к файлу lib должен быть добавлен в Linker -> General -> Additional Library Directories). При использовании сторонней библиотеки, которая предоставляется с файлом lib, отказ в этом обычно приводит к ошибке.

Также может случиться так, что вы забудете добавить файл в компиляцию, и в этом случае объектный файл не будет сгенерирован. В gcc вы должны добавить файлы в командную строку. В MSVS добавление файла в проект заставит его скомпилировать его автоматически (хотя файлы могут, вручную, быть отдельно исключены из сборки).

В программировании Windows контрольный знак, который вы не связывали необходимая библиотека состоит в том, что имя неразрешенного символа начинается с __imp_. Посмотрите имя функции в документации, и она должна сказать, какую библиотеку вам нужно использовать. Например, MSDN помещает информацию в поле внизу каждой функции в разделе «Библиотека».

36
задан Mario 15 February 2014 в 15:37
поделиться

7 ответов

Отключить отладку UIPageViewController

  1. Добавить делегата <UIScrollViewDelegate> в ваш заголовок UIPageViewController
  2. Установить для делегата UIScrollView UIPageViewController своих подчиненных родителям в viewDidLoad:
    for (UIView *view in self.view.subviews) {
        if ([view isKindOfClass:[UIScrollView class]]) {
            ((UIScrollView *)view).delegate = self;
            break;
        }
    }
    
  3. Реализация scrollViewDidScroll заключается в сбросе содержимого contentOffset в начало (NOT (0,0), но (bound.size.width, 0)), когда пользователь достигает границы, например :
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        if (_currentPage == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width) {
            scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
        } else if (_currentPage == totalViewControllersInPageController-1 && scrollView.contentOffset.x > scrollView.bounds.size.width) {
            scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
        }
    }
    
  4. Наконец, реализация scrollViewWillEndDragging связана с сценарием ошибок, когда пользователь быстро просматривает слева направо на первой странице, первая страница не будет отскакивать влево (из-за к функции выше), но будет отскок вправо, вызванный (возможно) скоростью салфетки. И, наконец, при возврате UIPageViewController вызовет переключение страницы на вторую страницу (что, конечно же, не ожидается).
    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
        if (_currentPage == 0 && scrollView.contentOffset.x <= scrollView.bounds.size.width) {
            *targetContentOffset = CGPointMake(scrollView.bounds.size.width, 0);
        } else if (_currentPage == totalViewControllersInPageController-1 && scrollView.contentOffset.x >= scrollView.bounds.size.width) {
            *targetContentOffset = CGPointMake(scrollView.bounds.size.width, 0);
        }
    }
    

Swift 4.0

Код для ввода в viewDidLoad:

for subview in self.view.subviews {
    if let scrollView = subview as? UIScrollView {
        scrollView.delegate = self
        break;
    }
}

Реализация для scrollViewDidScroll:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (currentPage == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width) {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0);
    } else if (currentPage == totalViewControllersInPageController - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width) {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0);
    }
}

Реализация для scrollViewWillEndDragging:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if (currentPage == 0 && scrollView.contentOffset.x <= scrollView.bounds.size.width) {
        targetContentOffset.pointee = CGPoint(x: scrollView.bounds.size.width, y: 0);
    } else if (currentPage == totalViewControllersInPageController - 1 && scrollView.contentOffset.x >= scrollView.bounds.size.width) {
        targetContentOffset.pointee = CGPoint(x: scrollView.bounds.size.width, y: 0);
    }
}
55
ответ дан Aleksandr Honcharov 26 August 2018 в 03:39
поделиться

UIPageViewController на самом деле мало что делает для вас. Вы можете использовать UIScrollView с контроллерами представлений довольно легко и отключить отскок на этом.

Просто сделайте что-то вроде

int x=0;
for (NSString *storyboardID in storyboardIDs){
        UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:storyboardID];
        [self addChildViewController:vc];
        vc.view.frame = CGRectMake(x++*vc.view.frame.size.width, 0, vc.view.frame.size.width, vc.view.frame.size.height);
        [self.scrollView addSubview:vc.view];
        [vc didMoveToParentViewController:self];
        self.scrollView.contentSize = CGSizeMake(storyboardIDs.count*vc.view.frame.size.width, vc.view.frame.size.height);
}
1
ответ дан arsenius 26 August 2018 в 03:39
поделиться

Я не знал, как правильно управлять currentIndex, но в итоге сделал

extension Main: UIPageViewControllerDelegate {
    func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if completed {
            guard let viewController = pageViewController.viewControllers?.first,
                index = viewControllerDatasource.indexOf(viewController) else {
                fatalError("Can't prevent bounce if there's not an index")
            }
            currentIndex = index
        }
    }
}
3
ответ дан Ashley Mills 26 August 2018 в 03:39
поделиться

Другой параметр - установить ScrollView.bounce = false. Он решил мою проблему с прокруткой прокрутки pageViewController (конечно, не про ScrollView). Откат отключен, и вся страница может прокручиваться без отскоков.

0
ответ дан colde 26 August 2018 в 03:39
поделиться

Отключить отладку UIPageViewController

Swift 2.2

Дополнение к ответам

1) Добавить UIScrollViewDelegate в UIPageViewController

extension PageViewController: UIScrollViewDelegate

2) Добавить в viewDidLoad

for view in self.view.subviews {
   if let scrollView = view as? UIScrollView {
      scrollView.delegate = self
   }
}

3) Добавить методы UIScrollViewDelegate

func scrollViewDidScroll(scrollView: UIScrollView) {
    if currentIndex == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
    } else if currentIndex == totalViewControllers - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
    }
}

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if currentIndex == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
    } else if currentIndex == totalViewControllers - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width {
        scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0)
    }
}
13
ответ дан Community 26 August 2018 в 03:39
поделиться

Изменить: не использовать это решение. После этого я узнал, что это вводит ошибку, где около 5% времени пользователь не может показывать страницу в одном направлении. Они должны вернуться на страницу, а затем переслать снова, чтобы продолжить.

Если вы используете UIPageViewControllerDataSource, относительно простой обходной путь (и немного взломанный) - отключить переключение при каждом вызове метода делегата pageViewController:viewControllerBeforeViewController:. Вот пример реализации:

@interface YourDataSourceObject ()
@property (strong, nonatomic) UIScrollView *scrollView;
@end

@implementation
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
    if (!self.scrollView) {
        for (UIView *view in pageViewController.view.subviews) {
            if ([view isKindOfClass:[UIScrollView class]]) {
                self.scrollView = (UIScrollView *)view;
            }
        }
    }
    self.scrollView.bounces = NO;

    // Your other logic to return the correct view controller. 
}
@end
0
ответ дан guptron 26 August 2018 в 03:39
поделиться

Если вы попытаетесь отключить отскок для UIPageViewController.scrollView, вы обязательно получите сломанный pageViewController: салфетка не сработает. Итак, не делайте этого:

self.theScrollView.alwaysBounceHorizontal = NO;
self.theScrollView.bounces = NO;

Используйте решение с помощью поиска scrollView в [sub] только для полного отключения прокрутки:

@interface MyPageViewController : UIPageViewController
@property (nonatomic, assign) BOOL scrollEnabled;
@end

@interface MyPageViewController ()
@property (nonatomic, weak) UIScrollView *theScrollView;
@end

@implementation MyPageViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    for (UIView *view in self.view.subviews) {
        if ([view isKindOfClass:UIScrollView.class]) {
            self.theScrollView = (UIScrollView *)view;
            break;
        }
    }
}

- (void)setScrollEnabled:(BOOL)scrollEnabled
{
    _scrollEnabled = scrollEnabled;
    self.theScrollView.scrollEnabled = scrollEnabled;
}

@end

Решение для отключение отката в UIPageViewController:

  1. Создать категорию UIScrollView (например, CustomScrolling). UIScrollView уже является делегатом своего распознавателя жестов.
  2. Имейте в виду, что ваша цель UIViewController (ака baseVC с UIPageViewController внутри) делится через AppDelegate. В противном случае вы можете использовать run-time (#import <objc/runtime.h>) и добавить свойство reference (к вашему контроллеру baseVC) в категорию.
  3. Категория реализации:
    @interface UIScrollView (CustomScrolling) <UIGestureRecognizerDelegate>
    @end
    
    @implementation UIScrollView (CustomScrolling)
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        UIViewController * baseVC = [(AppDelegate *)[[UIApplication sharedApplication] delegate] baseVC];
        if (gestureRecognizer.view == baseVC.pageViewController.theScrollView) {
            NSInteger page = [baseVC selectedIndex];
            NSInteger total = [baseVC viewControllers].count;
            UIPanGestureRecognizer *recognizer = (UIPanGestureRecognizer *)gestureRecognizer;
            CGPoint velocity = [recognizer velocityInView:self];
            BOOL horizontalSwipe = fabs(velocity.x) > fabs(velocity.y);
            if (!horizontalSwipe) {
                return YES;
            }
            BOOL scrollingFromLeftToRight = velocity.x > 0;
            if ((scrollingFromLeftToRight && page > 0) || (!scrollingFromLeftToRight && page < (total - 1))) {
                return YES;
            }
            return NO;
        }
        return YES;
    }
    
    @end
    
  4. Категория импорта файл #import "UIScrollView+CustomScrolling.h" в вашем baseVC, который использует UIPageViewController.
0
ответ дан sig 26 August 2018 в 03:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: