uitableview مع صور رأس القسم الجانبي
-
25-09-2019 - |
سؤال
يحتوي تطبيق الموسيقى على iPad على الكثير من ميزات واجهة المستخدم المخصصة المثيرة للاهتمام ، واحدة منها عرض الجدول المعروض عند النظر إلى ألبومات فنان معين.
إنه يحتوي على صور على جانب كل قسم ، يتصرف تقريبًا بطريقة مشابهة جدًا لوجهات نظر رأس القسم. إذا قمت بالتمرير لأسفل ، تبقى الصورة العلوية هناك حتى تأتي الصورة التالية لتصويرها ، والعكس صحيح.
في البداية ، يبدو من المستحيل تمامًا دون إعادة تنظيم UitableView مرة أخرى ، لكنني أعتقد أنه غير قابل للتطبيق ببساطة عن طريق التصنيف الفرعي لـ UableView لرسم هذه الصور على الجانب ، خارج UableView ، كلما اتصل layoutSubviews
(أي كلما تم تمريرها). هناك مشاكل طفيفة في هذا: نظرًا لأنه يرسم خارج UableView ، فمن المحتمل أن يلقي أي تلقائي على التخطيط بالكامل. وأنا حقًا غير متأكد من جدوى كل شيء.
أي أفكار؟
تحرير: لقد أدركت فقط أن فكرتي الأولى لن تعمل في أن أي لمسات على جانب الصور نفسها لن يتم تتبعها بواسطة TableView ، لذلك لم تتمكن من التمرير إذا لمست هناك. أعتقد أن أكبر مشكلة هنا هي معرفة كيفية نشر اللمسات بحيث يتم تتبع اللمسات عبر العرض بأكمله.
المحلول 2
بعد التفكير في الأمر بشكل عشوائي في منتصف الليل ، اكتشفت أخيرًا حلًا حقيقيًا.
قم بتضمين uitableview في مقابلة uiscrollview ، وعندما يقوم المستخدم بتمرير العرض ، تمر اللمسات من خلال Scrollview الأصل ، وليس TableView نفسه. كل ما تحتاجه للقيام به يكمن في طريقة LayoutSubviews ؛ نظرًا لأن LayoutSubViews من ScrollView يتم استدعاؤه عندما يقوم المستخدم بتمرير العرض ، فقط قم بتغيير إطار TableView للبقاء ثابتًا على الشاشة ، وتغيير محتوى TableView لمطابقة موقع Scrollview.
رمز المثال:
- (void) layoutSubviews{
tableView.frame = CGRectMake(self.contentOffset.x, self.contentOffset.y, tableView.frame.size.width, tableView.frame.size.height);
tableView.contentOffset = self.contentOffset;
}
في هذه المرحلة ، يمكنك ضبط TableView على جانب واحد ، والقيام بكل ما تريد من جهة أخرى.
نصائح أخرى
يمكنك التحقق من القسم الذي أنت موجود فيه في TableView (أو أعلى ما كذلك) بطريقة أو بأخرى ، ثم ببساطة لديك uiview يتم تحديثه كلما تغير القسم ، من الصعب توضيح فكرتي ، ولكن لن يكون لها علاقة بها Redoing UitableView على الإطلاق ، فقط احصل على طريقة عرض أخرى بجانب عرض الجدول للقيام بالصور بدلاً من محاولة تضمين هذه الوظيفة.
هناك طريقة أخرى للقيام بذلك ، ربما تكون أكثر صعوبة بعض الشيء ، لكن يمكنك محاولة مسافة بادئة لخلاياك حتى لا تبدأ من يسار الجدول ، وجعل عرض Tablevie الصورة على يسارها ونأمل أن تفعل ذلك بشكل صحيح؟ سؤال جيد وممتع للعب معه.
حسنًا ، لقد فعلت شيئًا مشابهًا لما يفعله تطبيق Music App و Spotlight Search.
لم أقم بدراسات فئة فرعية ، لقد قمت للتو بتتبع الأقسام من خلال طريقة ScrollViewDidsCroll ، وأضفت طرق عرض الرأس إلى يسار عرض TableView (لذلك سيتعين عليك وضع TableView على اليمين في عرض ViewController الخاص بك ، مما يعني أنه يمكنك ' T استخدم UitableViewController).
يجب استدعاء هذه الطريقة في ScrollViewDidsCroll و ViewDidload و DidrotateFromInterfaceorientation: (إذا كنت تدعم الدوران)
ضع في اعتبارك أنه سيتعين عليك توفير مساحة في اليسار مساوية لحجم الرؤوس في أي اتجاه واجهة تدعمها.
-(void)updateHeadersLocation
{
for (int sectionNumber = 0; sectionNumber != [self numberOfSectionsInTableView:self.tableView]; sectionNumber++)
{
// get the rect of the section from the tableview, and convert it to it's superview's coordinates
CGRect rect = [self.tableView convertRect:[self.tableView rectForSection:sectionNumber] toView:[self.tableView superview]];
// get the intersection between the section's rect and the view's rect, this will help in knowing what portion of the section is showing
CGRect intersection = CGRectIntersection(rect, self.tableView.frame);
CGRect viewFrame = CGRectZero; // we will start off with zero
viewFrame.size = [self headerSize]; // let's set the size
viewFrame.origin.x = [self headerXOrigin];
/*
three cases:
1. the section's origin is still showing -> header view will follow the origin
2. the section's origin isn't showing but some part of the section still shows -> header view will stick to the top
3. the part of the section that's showing is not sufficient for the view's height -> will move the header view up
*/
if (rect.origin.y >= self.tableView.frame.origin.y)
{
// case 1
viewFrame.origin.y = rect.origin.y;
}
else
{
if (intersection.size.height >= viewFrame.size.height)
{
// case 2
viewFrame.origin.y = self.tableView.frame.origin.y;
}
else
{
// case 3
viewFrame.origin.y = self.tableView.frame.origin.y + intersection.size.height - viewFrame.size.height;
}
}
UIView* view = [self.headerViewsDictionary objectForKey:[NSString stringWithFormat:@"%i", sectionNumber]];
// check if the header view is needed
if (intersection.size.height == 0)
{
// not needed, remove it
if (view)
{
[view removeFromSuperview];
[self.headerViewsDictionary removeObjectForKey:[NSString stringWithFormat:@"%i", sectionNumber]];
view = nil;
}
}
else if(!view)
{
// needed, but not available, create it and add it as a subview
view = [self headerViewForSection:sectionNumber];
if (!self.headerViewsDictionary && view)
self.headerViewsDictionary = [NSMutableDictionary dictionary];
if (view)
{
[self.headerViewsDictionary setValue:view forKey:[NSString stringWithFormat:@"%i", sectionNumber]];
[self.view addSubview:view];
}
}
[view setFrame:viewFrame];
}
}
كما نحتاج إلى إعلان خاصية من شأنها أن تبقي وجهات النظر المرئية:
@property (nonatomic, strong) NSMutableDictionary* headerViewsDictionary;
هذه الطرق تُرجع الحجم وإزاحة محور X لوجهات نظر الرأس:
-(CGSize)headerSize
{
return CGSizeMake(44.0f, 44.0f);
}
-(CGFloat)headerXOrigin
{
return 10.0f;
}
لقد قمت ببناء الرمز بحيث يتم إزالة أي عرض رأس غير مطلوب ، لذلك نحتاج إلى طريقة من شأنها أن تُرجع العرض كلما لزم الأمر:
-(UIView*)headerViewForSection:(NSInteger)index
{
UIImageView* view = [[UIImageView alloc] init];
if (index % 2)
{
[view setImage:[UIImage imageNamed:@"call"]];
}
else
{
[view setImage:[UIImage imageNamed:@"mail"]];
}
return view;
}
إليك كيف ستبدو:
كيف ستبدو في Lanscape ، لقد استخدمت تقارب لإعطاء 44 بكسل في يسار TableView
أتمنى أن يساعدك هذا :).