#ios #objective-c #uiscrollview
#iOS #objective-c #uiscrollview
Вопрос:
Я новичок в objective-c. Я создаю UIScrollView
объект и добавляю в свой вид с помощью этого кода:
height = self.view.frame.size.height;
width = self.view.frame.size.width;
scrollbar = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
scrollbar.delegate = self;
scrollbar.backgroundColor = [UIColor whiteColor];
scrollbar.maximumZoomScale = 1.0;
scrollbar.minimumZoomScale = 1.0;
scrollbar.clipsToBounds = YES;
scrollbar.showsHorizontalScrollIndicator = YES;
scrollbar.pagingEnabled = YES;
[scrollbar setContentSize:CGSizeMake(width*4, height*4)];
[self.view addSubview:scrollbar];
for (int i = 1; i <= 4; i ) {
first = [[FirstViewController alloc]initWithNibName:@"FirstViewController" bundle:nil];
first.view.frame = CGRectMake((i-1)*width, 0, width, height*4);
[scrollbar addSubview:first.view];
switch (i) {
ase 1:
first.view.backgroundColor = [UIColor blueColor];
break;
case 2:
first.view.backgroundColor = [UIColor redColor];
break;
case 3:
first.view.backgroundColor = [UIColor greenColor];
break;
case 4:
first.view.backgroundColor = [UIColor grayColor];
break;
default:
break;
}
}
в моем коде я добавляю 4 вида в моем ScrollView с другим цветом, теперь я хочу, чтобы при прокрутке в моем ScrollView определялись dx и dy (dx: расстояние движения по оси.x и dy: расстояние движения по оси.y) и проверял эти две переменные, и когда :
Примечание: я хочу, чтобы при любом касании ScrollView и перемещении касаний по оси (x или y) или касаний по обеим осям (x и y) проверялось это :
если (dx > dy) отключить горизонтальную прокрутку и перемещение в вертикальную сторону!!! иначе перемещение в горизонтальную сторону и отключение вертикальной прокрутки!!!
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGRect visibleRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, scrollView.contentOffset.x scrollView.bounds.size.width, scrollView.contentOffset.y scrollView.bounds.size.height);
NSLog(@"%f,%f",visibleRect.origin.x,visibleRect.origin.y);
/*NSLog(@"x : %f",scrollView.contentOffset.x);
NSLog(@"y : %f",scrollView.contentOffset.y);*/
if (fabsf(scrollView.contentOffset.x) > fabsf(scrollView.contentOffset.y)) {
NSLog(@"Vertical Side");
}
else {
NSLog(@"Horizontal Side");
}
}
пожалуйста, подскажите мне, ребята. Я не могу отключить одну сторону и переместить другую сторону!!! Спасибо
Ответ №1:
Если я правильно вас понял, вы хотите отключить прокрутку в направлении, которое меньше перетаскивалось пользователем. Если это так, UIScrollView уже предлагает такую возможность:
scrollView.directionalLockEnabled = YES;
Когда для этого параметра установлено значение true, UIScrollView сам обработает правильную блокировку направления.
Для получения дополнительной информации ознакомьтесь с документацией: ссылка
Комментарии:
1. мой друг, ты прав, но при двойном перетаскивании по обеим осям (x amp; y) прокрутка работает, а я этого не хочу.
Ответ №2:
Вы можете достичь желаемого результата, добавив некоторый код в свой делегат. Это мой ViewController.m
файл. -viewDidLoad
, #import
инструкции и другие методы опущены.
@interface ViewController () {
CGPoint initialOffset;
NSInteger direction; // 0 undefined, 1 horizontal, 2 vertical
}
@end
@implementation ViewController
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// retrieve current offset
CGPoint currentOffset = scrollView.contentOffset;
// do we know which is the predominant direction?
if (direction == 0) {
// no.
CGFloat dx = currentOffset.x - initialOffset.x;
CGFloat dy = currentOffset.y - initialOffset.y;
// we need to decide in which direction we are moving
if (fabs(dx) >= fabs(dy)) {
direction = 1; // horizontal
} else if (fabs(dy) > fabs(dx)) {
direction = 2;
}
}
// ok now we have the direction. update the offset if necessary
if (direction == 1 amp;amp; currentOffset.y != initialOffset.y) {
// remove y offset
currentOffset.y = initialOffset.y;
// update
[scrollView setContentOffset:currentOffset];
} else if (direction == 2 amp;amp; currentOffset.x != initialOffset.x) {
currentOffset.x = initialOffset.x;
[scrollView setContentOffset:currentOffset];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// store the current offset
initialOffset = scrollView.contentOffset;
// reset flag
direction = 0; // AKA undefined
}
@end
Когда вы начнете перетаскивание, делегат сбросит флаг direction
в состояние «неизвестно» и сохранит текущее смещение содержимого. После каждого перемещения будет вызываться ваш -scrollViewDidScroll:
. Там вы решаете, какое направление является преобладающим (если это еще не было сделано), и соответствующим образом корректируете текущее смещение прокрутки, удаляя смещение x (или y).
Я протестировал это с теми же настройками, которые вы предоставили, только я использовал UIImageView
inside UIScrollView
и настроил все через InterfaceBuilder, но это должно работать нормально. Теоретически, с помощью этого метода вы могли бы заменить directionLock
, но помните, что -scrollViewDidScroll
этот метод вызывается много раз во время действия, и каждый раз он перезаписывает смещение содержимого (если прокрутка происходит в обоих направлениях). Таким образом, если вы оставите directionLock
включенным, вы сохраните многие вызовы, setContentOffset:
которые выполняет делегат.