我有以下带有tableview和自定义单元格的viewcontroller:
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Linq;
using System.Threading;
using System.Data;
using System.IO;
using Mono.Data.Sqlite;
using System.Collections.Generic;
using Zurfers.Mobile.Core;
using AlexTouch.MBProgressHUD;
using System.Collections;
namespace Zurfers.Mobile.iOS
{
public partial class iPhoneHotelSearchViewController : UIViewController
{
MBProgressHUD hud;
public string Destination {
get;
set;
}
public DateTime CheckInDate {
get;
set;
}
public DateTime CheckOutDate {
get;
set;
}
public int Rooms {
get;
set;
}
public iPhoneHotelSearchViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
hud = new MBProgressHUD(this.View);
hud.Mode = MBProgressHUDMode.Indeterminate;
hud.LabelText = "Loading...";
hud.DetailsLabelText = "Searching Hotel";
this.View.AddSubview(hud);
hud.Show(true);
}
public override void ViewDidAppear (bool animated) {
base.ViewDidAppear (animated);
SearchHotel ();
}
public void SearchHotel (){
Hotel hotel = new Hotel();
var distribution = new HotelDistribution[]{new HotelDistribution(){ Adults = 1, Children = 0, ChildrenAges = new int[0]} };
var items = hotel.SearchHotels(Convert.ToDateTime("2013-08-08"),Convert.ToDateTime("2013-09-09 "),"(MIA)", distribution,"","","",0);
List<DtoHotelinformation> data = new List<DtoHotelinformation>();
foreach (var item in items)
{
DtoHotelinformation DtoHotelinformation = new DtoHotelinformation();
DtoHotelinformation.code = item.Code.ToString();
DtoHotelinformation.price = item.Price.ToString();
DtoHotelinformation.title = item.Name.ToString().ToTitleCase();
DtoHotelinformation.subtitle = item.Address.ToString();
DtoHotelinformation.rating = item.Rating.ToString();
DtoHotelinformation.imageUlr = item.ImageUrl;
data.Add(DtoHotelinformation);
}
hud.Hide(true);
hud.RemoveFromSuperview();
HotelSearchTable.Source = new HotelTableSource(data.ToArray());
HotelSearchTable.ReloadData();
}
partial void GoBack (MonoTouch.Foundation.NSObject sender)
{
DismissViewController(true, null);
}
}
}
现在表源
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Zurfers.Mobile.iOS
{
public class HotelTableSource : UITableViewSource
{
DtoHotelinformation[] tableItems;
NSString cellIdentifier = new NSString("TableCell");
public HotelTableSource (DtoHotelinformation[] items)
{
tableItems = items;
}
public override int RowsInSection (UITableView tableview, int section)
{
return tableItems.Length;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
//WHAT TO DO HERE
tableView.DeselectRow (indexPath, true); // normal iOS behaviour is to remove the blue highlight
}
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
CustomCell cell = tableView.DequeueReusableCell(cellIdentifier) as CustomCell;
if (cell == null)
cell = new CustomCell(cellIdentifier);
cell.UpdateCell(tableItems[indexPath.Row].title, tableItems[indexPath.Row].subtitle, tableItems[indexPath.Row].price,
tableItems[indexPath.Row].imageUlr, tableItems[indexPath.Row].rating );
return cell;
}
public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 70;
}
}
}
最后是自定义单元代码:
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.Dialog.Utilities;
namespace Zurfers.Mobile.iOS
{
public class CustomCell : UITableViewCell, IImageUpdated
{
UILabel headingLabel, subheadingLabel, priceLabel;
UIImageView imageService;
UIImageView star, star2, star3, star4, star5;
public CustomCell (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
{
imageService = new UIImageView();
star = new UIImageView();
star2 = new UIImageView();
star3 = new UIImageView();
star4 = new UIImageView();
star5 = new UIImageView();
headingLabel = new UILabel(){
Font = UIFont.FromName("Verdana-Bold", 14f),
BackgroundColor = UIColor.Clear,
TextColor = UIColor.FromRGB(241, 241, 211)
};
subheadingLabel = new UILabel(){
Font = UIFont.FromName("Verdana-Bold", 8f),
TextColor = UIColor.FromRGB(255, 255, 255),
BackgroundColor = UIColor.Clear
};
priceLabel = new UILabel(){
Font = UIFont.FromName("Verdana", 14f),
TextColor = UIColor.FromRGB(241, 241, 211),
BackgroundColor = UIColor.Clear
};
AddSubview(imageService);
AddSubview(headingLabel);
AddSubview(subheadingLabel);
AddSubview(priceLabel);
AddSubview(star);
AddSubview(star2);
AddSubview(star3);
AddSubview(star4);
AddSubview(star5);
}
public void UpdateCell (string title, string subtitle, string price, string imageUlr, string rating )
{
if (imageUlr != null) {
var u = new Uri(imageUlr);
ImageLoader MyLoader= new ImageLoader(50,50);
imageService.Image = MyLoader.RequestImage(u,this);
} else {
imageService.Image = UIImage.FromFile("generic_no_image_tiny.jpg");
}
headingLabel.Text = title;
subheadingLabel.Text = subtitle;
if (subtitle.Length > 40) {
subheadingLabel.LineBreakMode = UILineBreakMode.WordWrap;
subheadingLabel.Lines = 0;
}
switch (rating) {
case "T":
star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
break;
case "S":
star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
break;
case "F":
star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star4.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
break;
case "L":
star.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star2.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star3.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star4.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
star5.Image = UIImage.FromFile("ZurfersMovil-Stars.png");
break;
}
priceLabel.Text = "USD " + price;
priceLabel.Font = UIFont.BoldSystemFontOfSize (16);
}
public void UpdatedImage (Uri uri)
{
imageService.Image = ImageLoader.DefaultRequestImage(uri, this);
}
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
imageService.Frame = new RectangleF(10, 10, 50, 33);
headingLabel.Frame = new RectangleF(70, 4, 240, 25);
subheadingLabel.Frame = new RectangleF(70, 25, 240, 20);
priceLabel.Frame = new RectangleF(220, 45, 100, 20);
star.Frame = new RectangleF(70, 45, 15, 15);
star2.Frame = new RectangleF(85, 45, 15, 15);
star3.Frame = new RectangleF(100, 45, 15, 15);
star4.Frame = new RectangleF(115, 45, 15, 15);
star5.Frame = new RectangleF(130, 45, 15, 15);
}
}
}
当用户触摸表格视图的单元格时,我想打开另一个viewcontroller(iPhoneHotelDetailViewController)。但我不知道如何做到这一点。
你能帮帮我吗?提前感谢您的帮助。
答案 0 :(得分:3)
通常,您希望NavigationController成为应用中的“顶级”元素,包装所有其他控制器。
在AppDelegate中,创建一个NavigationController,并将其作为应用程序的根目录。
然后创建Search控制器的实例并将其推送到NavigationController。
最后,将一个NavigationController属性添加到TableSource的构造函数中。
NavigationController nav;
public HotelTableSource (DtoHotelinformation[] items, NavigationController nav)
{
this.nav = nav;
tableItems = items;
}
当你创建TableSource时,传递NavigationController引用。你可以这样做,因为所有ViewControllers都有一个指向它们的NavigationController的属性,如果它们包含在一个中。
HotelSearchTable.Source = new HotelTableSource(data.ToArray(), this.NavigationController);
最后,在RowSelected中,创建要显示的新ViewController的实例:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
//WHAT TO DO HERE
MyDetailController myDetail = new MyDetailController();
nav.PushViewController(myDetail, true);
tableView.DeselectRow (indexPath, true); // normal iOS behaviour is to remove the blue highlight
}
答案 1 :(得分:2)
我认为UINavigationController
中UITableViewSource
(UI组件)的链接有点奇怪。我建议使用基于事件的方法:
UITableViewSource
中声明事件并在行选择中调用它:public event Action<int> OnRowSelect;
...
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
tableView.DeselectRow (indexPath, true); // normal iOS behaviour is to remove the blue highlight
if (OnRowSelect != null) {
OnRowSelect(indexPath.Row);
}
}
UIViewController
处理事件 - 推送新UIViewController
:var source = data.ToArray();
source.OnRowSelect += HandleOnRowSelect;
HotelSearchTable.Source = new HotelTableSource();
HotelSearchTable.ReloadData();
...
void HandleOnRowSelect(int index)
{
var data = items[index];
// Pass data to new view controller and push it
}
提示避免内存泄漏:当您Pop
UIViewController
或创建新的UITableViewSource
实例时,请不要忘记取消订阅OnRowSelect。即:
source
; ViewWillDisappear
:source.OnRowSelect -= HandleOnRowSelect;
答案 2 :(得分:0)
如果您使用的是StoryBord,则有一种非常简单的方法可以做到这一点。然后,您可以像这样在PrepareForSegue方法中传递数据whit。
public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue (segue, sender);
NSIndexPath indexPatch = tableView.IndexPathForSelectedRow;
if (segue.Identifier.Equals ("showHotelDetail")) {
var vc = segue.DestinationViewController as iPhoneHotelDetailViewController;
if (vc != null) {
//Pass some date to the iPhoneHotelDetailViewController if needed.
vc.hotelName = this.tableItems [indexPatch.Row].hotelName;
}
}
}
在StoryBoard中,将customCell与iPhoneHotelDetailViewController连接,并调用segue“showHotelDetail”。