كيفية تقديم popover بشكل صحيح من uitableviewcell مع uipopoverarrowDirectionRight
-
26-09-2019 - |
سؤال
أحاول دائمًا تقديم popover من خلية داخل TableView بهذه الطريقة:
[myPopover presentPopoverFromRect:cell.frame inView:self.tableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
لكن لا يمكنني استخدام uipopoverarrowdirectionright أو اليسار ، لأنه ، اعتمادًا على موضع iPad (صورة أو مشهد) ، يظهر البوبوفر في مكان آخر.
هل أقدم البوبوفر بالطريقة الصحيحة؟
ملاحظة: طريقة عرض الجدول في عرض التفاصيل لـ splitview.
المحلول
هذا هو الحل البسيط الذي يعمل بشكل جيد بالنسبة لي
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect rect=CGRectMake(cell.bounds.origin.x+600, cell.bounds.origin.y+10, 50, 30);
[popOverController presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
نصائح أخرى
أنت تحصل على الإطار من الخلية عبر طريقة rectforoRovIndexPath. هذا صحيح. ومع ذلك ، من المرجح أن يكون عرض TableView نظرة فرعية على طريقة عرض iPad أكبر ، لذا عندما يحصل Popover على الإحداثيات ، فإنها تعتقد أنها في العرض الأكبر. هذا هو السبب في ظهور البوبوفر في المكان الخطأ.
على سبيل المثال ، CGRECT للصف هو (0،40،320،44). بدلاً من استهداف هذا الإطار على Tableview ، يستهدف هذا الإطار بدلاً من ذلك على العرض الرئيسي.
لقد حلت هذه المشكلة عن طريق تحويل الإطار من الإحداثيات النسبية للجدول إلى الإحداثيات في وجهة نظري الأكبر.
الشفرة:
CGRect aFrame = [self.myDetailViewController.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:theRow inSection:1]];
[popoverController presentPopoverFromRect:[self.myDetailViewController.tableView convertRect:aFrame toView:self.view] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
آمل أن يساعد الآخرين في البحث عن هذه المسألة.
صادفت هذه المشكلة اليوم ، ووجدت حلاً أبسط.
عند إنشاء إنشاء Popover ، تحتاج إلى تحديد عرض محتوى الخلية:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *aViewController = [[UIViewController alloc] init];
// initialize view here
UIPopoverController *popoverController = [[UIPopoverController alloc]
initWithContentViewController:aViewController];
popoverController.popoverContentSize = CGSizeMake(320, 416);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[popoverController presentPopoverFromRect:cell.bounds inView:cell.contentView
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[aView release];
// release popover in 'popoverControllerDidDismissPopover:' method
}
في Swift ، بين الإجابات أعلاه ، يعمل هذا الأمر بالنسبة لي على جهاز iPad في أي اتجاه:
if let popOverPresentationController : UIPopoverPresentationController = myAlertController.popoverPresentationController {
let cellRect = tableView.rectForRowAtIndexPath(indexPath)
popOverPresentationController.sourceView = tableView
popOverPresentationController.sourceRect = cellRect
popOverPresentationController.permittedArrowDirections = UIPopoverArrowDirection.Any
}
لتثبيط بوبوفر بجانب Accesory ، يمكنك استخدام هذا الرمز :)
أنا استخدم هذا للمزيد الاستخدام المتقدم:
- يجد مخصص AccesoryView (Cell.ACCESORYVIEW)
- إذا كان فارغًا ، ابحث
- إذا لم يكن Uibultton موجودًا ، ابحث عن Cell Contet View (UitableViewCellContentView)
- إذا لم يكن عرض قصوى الخلية موجودًا ، فاستخدم طريقة عرض الخلية
يمكن أن تستخدم ل uiactionsheet أو uipopovercontroller.
ها هو رمزتي:
UIView *accessoryView = cell.accessoryView; // finds custom accesoryView (cell.accesoryView)
if (accessoryView == nil) {
UIView *cellContentView = nil;
for (UIView *accView in [cell subviews]) {
if ([accView isKindOfClass:[UIButton class]]) {
accessoryView = accView; // find generated accesoryView (UIButton)
break;
} else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
// find generated UITableViewCellContentView
cellContentView = accView;
}
}
// if the UIButton doesn't exists, find cell contet view (UITableViewCellContentView)
if (accessoryView == nil) {
accessoryView = cellContentView;
}
// if the cell contet view doesn't exists, use cell view
if (accessoryView == nil) {
accessoryView = cell;
}
}
[actionSheet showFromRect:accessoryView.bounds inView:accessoryView animated:YES];
تم اختباره في iOS 4.3 إلى 5.1
من الأفضل استخدامها كطريقة مخصصة:
-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell;
ورمز الطريقة:
-(UIView*)getViewForSheetAndPopUp:(UITableViewCell*)cell {
UIView *accessoryView = cell.accessoryView;
if (accessoryView == nil) {
UIView *cellContentView = nil;
for (UIView *accView in [cell subviews]) {
if ([accView isKindOfClass:[UIButton class]]) {
accessoryView = accView;
break;
} else if ([accView isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
cellContentView = accView;
}
}
if (accessoryView == nil) {
accessoryView = cellContentView;
}
if (accessoryView == nil) {
accessoryView = cell;
}
}
return accessoryView;
}
لقد صادفت هذه المشكلة أيضًا. كان الحل بالنسبة لي هو تغيير عرض المستقيم الذي تم إرجاعه بواسطة CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath
:
CGRect rect = [aTableView rectForRowAtIndexPath:indexPath];
//create a 10 pixel width rect at the center of the cell
rect.origin.x = (rect.size.width - 10.0) / 2.0;
rect.size.width = 10.0;
[self.addExpensePopoverController presentPopoverFromRect:rect inView:aTableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
هذا يخلق مستقيم مركز داخل الخلية. وبهذه الطريقة ، يتمتع البوبوفر بمزيد من فرص FindInd بقعة جيدة لوضع نفسها.
سيكون إطار الخلية مثل 0،0 ، العرض ، الحجم ، لا أعتقد أنه سيكون له x و y بالنسبة لمرض الجدول ... تريد استخدامه - (cgrect) rectforrowatindexpath: (nsindexpath *) indexpath هذا ، هذا يجب أن يعيد لك الإطار الصحيح للخلية بالنسبة إلى TableView ... إليك رابط uitableview المرجع
واجهت نفس النوع من المشكلة ، إليك الحل البديل الذي استخدمته:
- في uitableViewCell ، أضفت إجراءات (ibactions وأنا أقوم بإنشاء خلويتي من NIB) للأزرار المحددة للخلية.
- ثم قمت بتعريف بروتوكول CellActionDelegate الذي يحاكي محددات الإجراءات الخاصة بي ، والذي كان لدي زر (المرسل) وخليتي (الذات)
- ثم ينفذ DelieveViewController الخاص بـ splitviewController هذا البروتوكول ، ويتحول من الخلية إلى إحداثياتها ...
هنا مثال على الكود
في MyCustomTableViewCell.M:
-(IBAction)displaySomeCellRelativePopover:(id)sender{
//passes the actions to its delegate
UIButton *button = (UIButton *)sender;
[cellActionDelegate displaySomeCellRelativePopoverWithInformation:self.info
fromButton:button
fromCell:self];
}
و ، في myDetailViewController.M:
-(void)displaySomeCellRelativePopoverWithInformation:(MyCellInformationClass *)info
fromButton:(UIButton *)button
fromCell:(UIView *)cell{
UIPopoverController * popoverController = nil;
//create your own UIPopoverController the way you want
//Convert your button/view frame
CGRect buttonFrameInDetailView = [self.view convertRect:button.frame fromView:cell];
//present the popoverController
[popoverController presentPopoverFromRect:buttonFrameInDetailView
inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];]
//release objects created...
}
ملاحظة: بالطبع ، لا يجب أن يكون "الإجراء" عبارة عن ibaction ، والإطار من المكان الذي ينشأ فيه البوبوفر لا يجب أن يكون Uibultton - ستكون Uiview واحدة جيدة :)
هكذا فعلت وتعمل بشكل جيد تمامًا.
RidersVC *vc = [RidersVC ridersVC];
vc.modalPresentationStyle = UIModalPresentationPopover;
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
UIPopoverPresentationController *popPresenter = [vc popoverPresentationController];
popPresenter.sourceView = vc.view;
popPresenter.barButtonItem= [[UIBarButtonItem alloc] initWithCustomView:button];
popPresenter.backgroundColor = [UIColor colorWithRed:220.0f/255.0f green:227.0f/255.0f blue:237.0f/255.0f alpha:1.0];
[self.parentVC presentViewController:vc animated:YES completion:NULL];
هذه أيضا عملت بالنسبة إلي:
//Which are the ABSOLUTE coordinates in from the current selected cell CGRect frame =[self.view convertRect:[tbvEventsMatch rectForRowAtIndexPath:indexPath] fromView:tbvEventsMatch.viewForBaselineLayout];
لا يمكن تجميع الإجابة المقبولة الآن.
CGRect rect =[tableView rectForRowAtIndexPath:indexPath]; //This is how to get the correct position on the tableView
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.sourceRect = rect;
popController.permittedArrowDirections = 0; //Here there is no arrow. It is my app's need
popController.delegate = self;
popController.sourceView = self.tableView;
popController.sourceView.backgroundColor = [UIColor yellowColor];