আপনি খুব কঠিন পরিস্থিতিতে আছেন, আমাকে অবশ্যই বলতে হবে।
নোট করুন যে pagingEnabled=YES
পৃষ্ঠাগুলির মধ্যে স্যুইচ করতে আপনার একটি ইউআইএসক্রোলভিউ ব্যবহার করা দরকার তবে আপনাকে pagingEnabled=NO
উল্লম্বভাবে স্ক্রোল করা দরকার ।
সম্ভাব্য 2 কৌশল রয়েছে। আমি জানি না কোনটি কার্যকর হবে / কার্যকর করা সহজ, তাই উভয়ই চেষ্টা করে দেখুন।
প্রথম: নেস্টেড ইউআইএসক্রোলভিউস। সত্যই, আমি এখনও এমন একজনকে দেখতে পাচ্ছি না যিনি এই কাজ করতে পেরেছেন। তবে আমি ব্যক্তিগতভাবে যথেষ্ট চেষ্টা করে দেখিনি, এবং আমার অনুশীলনটি দেখায় যে আপনি যখন যথেষ্ট চেষ্টা করেন, আপনি ইউআইএসক্রোলভিউকে আপনার পছন্দমতো কিছু করতে পারেন ।
সুতরাং কৌশলটি হ'ল বাইরের স্ক্রোল ভিউটি কেবল অনুভূমিক স্ক্রোলিং এবং অভ্যন্তরীণ স্ক্রোল ভিউগুলি কেবল উল্লম্ব স্ক্রোলিং পরিচালনা করতে দেয়। এটি সম্পাদন করতে, আপনাকে অবশ্যই জানতে হবে ইউআইএসক্রলভিউ অভ্যন্তরীণভাবে কীভাবে কাজ করে। এটি hitTest
পদ্ধতিটিকে ওভাররাইড করে এবং সর্বদা নিজেই ফিরে আসে, যাতে সমস্ত স্পর্শ ইভেন্টগুলি ইউআইএসক্রোলভিউতে যায়। তারপরে ভিতরে touchesBegan
, touchesMoved
ইত্যাদি এটি ইভেন্টে আগ্রহী কিনা তা পরীক্ষা করে এবং এটি পরিচালনা করে বা অভ্যন্তরীণ উপাদানগুলিতে প্রেরণ করে।
স্পর্শটি পরিচালনা করতে হবে বা ফরোয়ার্ড করা হবে কিনা তা সিদ্ধান্ত নিতে, ইউআইএসক্রোলভিউ যখন আপনি প্রথম স্পর্শ করেন তখন একটি টাইমার শুরু করে:
যদি আপনি 150 মিটারের মধ্যে উল্লেখযোগ্যভাবে আপনার আঙুলটি সরান না, তবে ইভেন্টটি অভ্যন্তরীণ দৃশ্যে চলে যায়।
যদি আপনি 150 মিটারের মধ্যে উল্লেখযোগ্যভাবে আপনার আঙুলটি স্থানান্তরিত করে থাকেন তবে এটি স্ক্রোলিং শুরু হয় (এবং কখনই ইভেন্টটি অভ্যন্তরীণ দৃশ্যে পাস করে না)।
আপনি কীভাবে কোনও টেবিলটি স্পর্শ করবেন (যা স্ক্রোল ভিউয়ের একটি সাবক্লাস) এবং ততক্ষণে স্ক্রোলিং শুরু করবেন, আপনি যে সারিটি স্পর্শ করেছেন তা কখনই হাইলাইট হয় না।
আপনি যদি না 150ms মধ্যে উল্লেখযোগ্যভাবে আপনার আঙুল সরানো এবং UIScrollView ভেতরের দৃশ্যে ঘটনা ক্ষণস্থায়ী শুরু করেছিলাম, কিন্তু তারপর আপনি শুরু করার স্ক্রলিং, UIScrollView আহ্বান জন্য খুব বেশী কথা আঙুল সরানো হয়েছে touchesCancelled
ভেতরের দৃশ্য এবং শুরু হয় স্ক্রলিং।
আপনি যখন কোনও টেবিলটি স্পর্শ করেন তখন কীভাবে আপনার আঙুলটি কিছুটা ধরে রাখুন এবং তারপরে স্ক্রোলিং শুরু করুন, আপনি যে সারিটি স্পর্শ করেছেন তা প্রথমে হাইলাইট করা হবে তবে পরে ডি-হাইলাইট হবে Note
ইভেন্টগুলির এই ক্রমটি ইউআইএসক্রোলভিউয়ের কনফিগারেশনের মাধ্যমে পরিবর্তিত হতে পারে:
- যদি
delaysContentTouches
না হয়, তবে কোনও টাইমার ব্যবহার করা হয় না - ইভেন্টগুলি তত্ক্ষণাত্ অভ্যন্তরীণ নিয়ন্ত্রণে চলে যায় (তবে আপনি যদি আপনার আঙুলটি যথেষ্ট পরিমাণে সরান তবে বাতিল হয়ে যায়)
- যদি
cancelsTouches
না হয়, তবে ইভেন্টগুলি একবার নিয়ন্ত্রণে প্রেরণ করা হলে, স্ক্রোলিং কখনই ঘটবে না।
মনে রাখবেন যে UIScrollView যে পায় সব touchesBegin
, touchesMoved
, touchesEnded
এবং touchesCanceled
CocoaTouch থেকে ইভেন্টগুলি (কারণ এটির hitTest
সে কি এটি করতে বলে)। এটি এটি যতক্ষণ চাইলে অভ্যন্তরীণ দৃশ্যে ফরোয়ার্ড করে।
আপনি এখন ইউআইএসক্রোলভিউ সম্পর্কে সমস্ত কিছু জানেন, আপনি এর আচরণটি পরিবর্তন করতে পারেন। আমি বাজি ধরতে পারি যে আপনি উল্লম্ব স্ক্রোলিংকে অগ্রাধিকার দিতে চান, যাতে ব্যবহারকারী একবার দৃষ্টি আকর্ষণ করে এবং তার আঙুলটি (এমনকি সামান্য) চালানো শুরু করে, দর্শনটি উল্লম্ব দিকে স্ক্রোলিং শুরু করে; তবে যখন ব্যবহারকারী তার আঙুলটি অনুভূমিক দিকের দিকে যথেষ্ট পরিমাণে সরান, আপনি উলম্ব স্ক্রোলিং বাতিল করতে এবং অনুভূমিক স্ক্রোলিং শুরু করতে চান।
আপনি আপনার বাহ্যিক ইউআইএসক্রোলভিউটি সাবক্লাস করতে চান (বলুন, আপনি নিজের শ্রেণীর নাম রাখেন রিসরসফুলসক্রোলভিউ), যাতে ডিফল্ট আচরণের পরিবর্তে এটি তাত্ক্ষণিকভাবে সমস্ত ইভেন্টকে অভ্যন্তরীণ দৃশ্যে ফরোয়ার্ড করে দেয় এবং কেবলমাত্র যখন অনুভূমিক আন্দোলন সনাক্ত হয় তখন এটি স্ক্রোল হয়।
রিমর্সফুলসক্রোলভিউকে কীভাবে এমন আচরণ করা যায়?
দেখে মনে হচ্ছে উল্লম্ব স্ক্রোলিংটি অক্ষম করা এবং delaysContentTouches
NO এ সেট করার ফলে নেস্টেড ইউআইএসক্রোলভিউগুলি কাজ করা উচিত। দুর্ভাগ্যক্রমে, এটি না; ইউআইএসক্রোলভিউ দ্রুত গতির (যা অক্ষম করা যায় না) জন্য কিছু অতিরিক্ত ফিল্টারিং করতে দেখা যায়, যাতে ইউআইএসক্রোলভিউ কেবল অনুভূমিকভাবে স্ক্রোল করা যায়, তবে এটি সর্বদা যথেষ্ট পরিমাণে উল্লম্ব গতি খায় (এবং উপেক্ষা করবে)।
প্রভাবটি এত মারাত্মক যে নেস্টেড স্ক্রোল ভিউয়ের অভ্যন্তরে উল্লম্ব স্ক্রোলিংটি ব্যবহারযোগ্য নয়। (মনে হচ্ছে আপনি ঠিক এই সেটআপটি পেয়েছেন, তাই এটি চেষ্টা করে দেখুন: 150 মিমি ধরে একটি আঙুল ধরে এবং তারপরে এটি উল্লম্ব দিকে চালিত করুন - নেস্টেড ইউআইএসক্রোলভিউ তখন প্রত্যাশার মতো কাজ করে!)
এর অর্থ আপনি ইভেন্ট হ্যান্ডলিংয়ের জন্য ইউআইএসক্রোলভিউ কোড ব্যবহার করতে পারবেন না; আপনাকে রিমর্সফুলসক্রোলভিউতে চারটি টাচ হ্যান্ডলিং পদ্ধতি ওভাররাইড করতে হবে এবং প্রথমে আপনার নিজের প্রসেসিং super
করতে হবে, যদি আপনি অনুভূমিক স্ক্রোলিংয়ের সাথে যাওয়ার সিদ্ধান্ত নিয়ে থাকেন তবে ইভেন্টটিকে কেবল (ইউআইএসক্রোলভিউ) ফরোয়ার্ড করতে হবে।
তবে আপনি পাস করতে হবে touchesBegan
, কারণ আপনি এটা (যদি আপনি পরে সিদ্ধান্ত নেন এটা একটি বেস ভবিষ্যৎ অনুভূমিক স্ক্রলিং জন্য তুল্য মনে রাখতে চান UIScrollView করতে হয় একটি অনুভূমিক স্ক্রলিং)। আপনি touchesBegan
পরে ইউআইএসক্রোলভিউতে প্রেরণ করতে পারবেন না, কারণ আপনি touches
যুক্তিটি সংরক্ষণ করতে পারবেন না : এটিতে এমন বস্তু রয়েছে যা পরের touchesMoved
ইভেন্টের আগে রূপান্তরিত হবে এবং আপনি পুরানো অবস্থায় পুনরুত্পাদন করতে পারবেন না।
সুতরাং আপনাকে touchesBegan
অবিলম্বে ইউআইএসক্রোলভিউতে যেতে হবে, তবে আপনি touchesMoved
যতক্ষণ না অনুভূমিকভাবে স্ক্রোল করার সিদ্ধান্ত নেন ততক্ষণ আপনি এ থেকে আর কোনও ইভেন্ট লুকিয়ে রাখবেন । এর touchesMoved
অর্থ কোনও স্ক্রোলিং নয়, সুতরাং এই প্রাথমিকটি touchesBegan
কোনও ক্ষতি করবে না। তবে delaysContentTouches
কোনটি সেট করবেন না, যাতে কোনও অতিরিক্ত বিস্ময়কর টাইমাররা হস্তক্ষেপ না করে।
(Offtopic - আপনি মতো UIScrollView করতে ছোঁয়া সঠিকভাবে সংরক্ষণ এবং পুননির্মান ও ফরোয়ার্ড মূল পারেন touchesBegan
, যাতে করতে পারেন ক্লোন স্পর্শ বস্তু আগে তারা ভাবে পরিবর্তিত হয় ঘটনা পরে অপ্রকাশিত API গুলি ব্যবহার করে একটি অন্যায্য সুবিধা রয়েছে।।)
আপনি সর্বদা ফরোয়ার্ড দিয়েছিলেন touchesBegan
, আপনাকেও ফরওয়ার্ড করতে হবে touchesCancelled
এবং touchesEnded
। আপনি চালু আছে touchesEnded
মধ্যে touchesCancelled
অবশ্য কারণ UIScrollView অর্থ করবেন touchesBegan
, touchesEnded
একটি স্পর্শ-ক্লিক যেমন ক্রম এবং ভিতরের দেখতে এটিকে ফরোয়ার্ড হবে। আপনি ইতিমধ্যে যথাযথ ইভেন্টগুলি নিজেই ফরোয়ার্ড করছেন, তাই আপনি কখনই ইউআইএসক্রোলভিউকে কিছু ফরোয়ার্ড করতে চান না।
আপনার যা করা দরকার তা মূলত এখানে সিউডোকোড। সরলতার জন্য, মাল্টিটাচ ইভেন্টটি আসার পরে আমি কখনই অনুভূমিক স্ক্রোলিংকে অনুমতি দিই না।
@interface RemorsefulScrollView : UIScrollView {
CGPoint _originalPoint;
BOOL _isHorizontalScroll, _isMultitouch;
UIView *_currentChild;
}
@end
#define kThresholdX 12.0f
#define kThresholdY 4.0f
@implementation RemorsefulScrollView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.delaysContentTouches = NO;
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super initWithCoder:coder]) {
self.delaysContentTouches = NO;
}
return self;
}
- (UIView *)honestHitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *result = nil;
for (UIView *child in self.subviews)
if ([child pointInside:point withEvent:event])
if ((result = [child hitTest:point withEvent:event]) != nil)
break;
return result;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
if (_isHorizontalScroll)
return;
if ([touches count] == [[event touchesForView:self] count]) {
_originalPoint = [[touches anyObject] locationInView:self];
_currentChild = [self honestHitTest:_originalPoint withEvent:event];
_isMultitouch = NO;
}
_isMultitouch |= ([[event touchesForView:self] count] > 1);
[_currentChild touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (!_isHorizontalScroll && !_isMultitouch) {
CGPoint point = [[touches anyObject] locationInView:self];
if (fabsf(_originalPoint.x - point.x) > kThresholdX && fabsf(_originalPoint.y - point.y) < kThresholdY) {
_isHorizontalScroll = YES;
[_currentChild touchesCancelled:[event touchesForView:self] withEvent:event]
}
}
if (_isHorizontalScroll)
[super touchesMoved:touches withEvent:event];
else
[_currentChild touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (_isHorizontalScroll)
[super touchesEnded:touches withEvent:event];
else {
[super touchesCancelled:touches withEvent:event];
[_currentChild touchesEnded:touches withEvent:event];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
if (!_isHorizontalScroll)
[_currentChild touchesCancelled:touches withEvent:event];
}
@end
আমি এটি চালানোর বা এমনকি সংকলনের চেষ্টা করিনি (এবং একটি সম্পূর্ণ পাঠ্য সম্পাদককে পুরো ক্লাসটি টাইপ করেছেন), তবে আপনি উপরেরটি দিয়ে শুরু করতে পারেন এবং আশা করি এটি কাজ করে চলেছে।
আমি দেখি কেবল লুকানো ধরাটি হ'ল আপনি যদি রিমসারফুলসক্রোলভিউতে কোনও অ-ইউআইএসক্রোলভিউ চাইল্ড ভিউ যুক্ত করেন তবে আপনার কোনও সন্তানের কাছে ফর্চার করা স্পর্শ ইভেন্টগুলি প্রতিক্রিয়াশীল চেইনের মাধ্যমে আপনার কাছে ফিরে আসতে পারে, যদি শিশু সবসময় ইউআইএসক্রোলভিউয়ের মতো স্পর্শগুলি পরিচালনা না করে। একটি বুলেট-প্রমাণ রিমর্সফুলসক্রোলভিউ বাস্তবায়ন রিেন্ট্রি থেকে রক্ষা করবে touchesXxx
।
দ্বিতীয় কৌশল: যদি কোনও কারণে নেস্টেড ইউআইএসক্রোলভিউগুলি কার্যকর না হয় বা ডান পেতে খুব কঠিন প্রমাণিত না হয় তবে আপনি কেবলমাত্র একটি ইউআইএসক্রোলভিউয়ের সাথে যেতে চেষ্টা করতে পারেন, pagingEnabled
আপনার scrollViewDidScroll
প্রতিনিধি পদ্ধতি থেকে ফ্লাইতে তার সম্পত্তিটি স্যুইচ করে ।
তির্যকীয় স্ক্রোলিং রোধ করতে আপনার প্রথমে কন্টেন্টঅফসেটটি মনে রাখা scrollViewWillBeginDragging
এবং কন্টেন্টআফেসটি চেক করা এবং পুনরায় সেট করার চেষ্টা করা উচিত scrollViewDidScroll
যদি আপনি একটি তির্যক গতিবিধি সনাক্ত করেন। আরেকটি কৌশল চেষ্টা করার বিষয় হ'ল কন্টেন্টসাইজটি কেবলমাত্র এক দিকে স্ক্রোলিং সক্ষম করার জন্য, একবার আপনি সিদ্ধান্ত নেন যে ব্যবহারকারীর আঙুলটি কোন দিকে যাচ্ছে। (ইউআইএসক্রোলভিউ এর প্রতিনিধি পদ্ধতিগুলি থেকে কন্টেন্টসাইজ এবং কন্টেন্টঅফসেটের সাথে ফিডিং সম্পর্কে বেশ ক্ষমাশীল বলে মনে হচ্ছে))
যে পঙ্কিল ভিজ্যুয়াল কাজ করুন অথবা ফলাফল না থাকে, তাহলে আপনি ওভাররাইড করতে হবে touchesBegan
, touchesMoved
ইত্যাদি এবং UIScrollView না এগিয়ে তির্যক আন্দোলন ইভেন্ট নেই। (তবে ব্যবহারকারীর অভিজ্ঞতা এক্ষেত্রে সাবঅস্টিমাল হবে, কারণ আপনাকে একক দিকের দিকে চাপ দেওয়ার পরিবর্তে তির্যক গতিবিধিগুলি উপেক্ষা করতে হবে you're আপনি যদি সত্যিই সাহসী বোধ করেন তবে আপনি নিজের ইউআইটিউচ লুকিয়াকে লিখতে পারেন, রিভেঞ্জটচের মতো কিছু j উদ্দেশ্য) -সি সরল পুরাতন সি, এবং পৃথিবীতে সি-এর চেয়ে বেশি দুষ্টু কিছু নেই; যতক্ষণ না নূন যতক্ষণ না আমার বিশ্বাস বিশ্বাসযোগ্য বস্তুর আসল শ্রেণি পরীক্ষা করে, আপনি যে কোনও শ্রেণিকে অন্য শ্রেণীর মতো দেখতে পারেন like এটি খোলে। আপনার চাইলে যে কোনও ছোঁয়া, যে কোনও স্থানাঙ্কের সাথে সংশ্লেষ করার সম্ভাবনা))
ব্যাকআপ কৌশল: টিটিএসক্রোলভিউ রয়েছে, থ্রি -20 লাইব্রেরিতে ইউআইএসক্রোলভিউয়ের বুদ্ধিমান পুনরায় বাস্তবায়ন । দুর্ভাগ্যক্রমে এটি ব্যবহারকারীর কাছে খুব অপ্রাকৃত এবং আইফোনিশ বোধ করে। তবে যদি ইউআইএসক্রোলভিউ ব্যবহারের প্রতিটি প্রচেষ্টা ব্যর্থ হয়, আপনি কাস্টম-কোডেড স্ক্রোল দৃশ্যে ফিরে যেতে পারেন। আমি যদি সম্ভব হয় তবে এর বিরুদ্ধে সুপারিশ করছি; ইউআইএসক্রোলভিউ ব্যবহার করে এটি নিশ্চিত করে যে আপনি ভবিষ্যতের আইফোন ওএস সংস্করণগুলিতে এটি কীভাবে বিকশিত হয় তা দেশীয় চেহারা এবং অনুভূতি পাচ্ছে।
ঠিক আছে, এই ছোট্ট প্রবন্ধটি কিছুটা দীর্ঘ হয়েছে। বেশ কয়েকদিন আগে স্ক্রলিংম্যাডনেস কাজ করার পরে আমি কেবল এখনও ইউআইএসক্রোলভিউ গেমসে আছি।
পিএস যদি আপনি এইগুলির মধ্যে কোনও কাজ পেয়ে থাকেন এবং ভাগ করে নেওয়ার মত বোধ করেন তবে অনুগ্রহ করে আমাকে andreyvit@gmail.com এ প্রাসঙ্গিক কোডটি ইমেল করুন, আমি আনন্দের সাথে এটিকে আমার স্ক্রোলিংম্যাডেস ব্যাগের কৌশলগুলিতে অন্তর্ভুক্ত করব ।
পিপিএস এই ছোট্ট প্রবন্ধটি স্ক্রোলিংম্যাডনেস রিডমিতে যুক্ত করা হচ্ছে।