码迷,mamicode.com
首页 > 移动开发 > 详细

FlipView For Xamarin.Form 之 IOS

时间:2015-10-26 00:21:08      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

之前写过两篇博文 是关于 Android 和 Windows Phone 下的 FlipView 的实现。

上上周,有个印度佬通过 GitHub 找到我, 问我有没有打算个 ios 端的,还说比较了相同功能的几个开源项目,我的这个项目值得推荐。说的我心潮澎湃,上周末花了一个周末升级到最新的 XCode 7,顺便也升级到了 OS X EI Capitan, 安装了最新的 Xamarin, 使用了 IOS 9 提供的免费证书,终于于今天凌晨1点(10月25)把 ios 端的 renderer 给写出来了。

先上效果图:

技术分享

项目地址:

https://github.com/gruan01/FlipView

支持 ios / Android / Windows Phone

 

相比之下,ios 的实现最简单, 只用了 UIScrollView + UIPageControl (白点) 就完成了,代码易于理解。

https://github.com/gruan01/FlipView/blob/master/FlipView/FlipView.iOS/Controls/FlipView.cs

 

Android 下使用了 PageAdapter + ViewPager + 一堆的点缀,控制点N多,不易阅读理解。

Windows Phone 下从 ItemsControl 扩展出来一个新控件,还算清晰吧。

 

本文主要介绍 ios 端,其它请参考:

Xamarin 实现 Android 无限循环展示, FlipView

挣扎着写 FlipView For Xamarin.Form

 

UIScrollView 可以设置分页(PagingEnable), 这个特性满足 FlipView 的需求。

如果要有分页效果, UIScrollView 的 ContentSize 必须大于它的 Frame.

要使每一页上都有衔接的内容显示,必须按 X 或 Y 方向对子 View 进行布局:

 1         public override void LayoutSubviews() {
 2             base.LayoutSubviews();
 3 
 4             var w = this.Frame.Size.Width;
 5             var h = this.Frame.Size.Height;
 6             for (var i = 0; i < this.Views.Count; i++) {
 7                 var v = this.Subviews[i];
 8 
 9                 var rect = new CGRect(w * i, 0, w, h);
10                 v.Frame = rect;
11             }
12 
13             this.ContentSize = new CGSize(w * this.Views.Count, h);
14         }

 

要知道当前显示的是哪一页,需要监听 UIScrollView 的 Scrolled 事件:

1             this.Scrolled += FlipView_Scrolled;
2         }
3 
4         void FlipView_Scrolled(object sender, EventArgs e) {
5             var pageWidth = this.Frame.Size.Width;
6             var page = (int)Math.Floor((this.ContentOffset.X - pageWidth / 2) / pageWidth) + 1;
7             this.PageControl.CurrentPage = page;
8         }

 

 

this.PageControl 就是那几个白点,只负卖萌。 注意不要把它做为 UIScrollView 的子视图了, 它应该是和 UIScrollView 同一个父级的,要不然,这几个白点就会在切换页面的时候同时被滚来滚去。

 1         protected override void OnElementChanged(ElementChangedEventArgs<Flip> e) {
 2             base.OnElementChanged(e);
 3 
 4             var fv = new Controls.FlipView();
 5             var items = this.GetChildrenViews().ToList();
 6             fv.SetItems(items);
 7 
 8             this.SetNativeControl(fv);
 9             this.Control.SizeToFit();
10             this.AddSubview(this.Control.PageControl);
11         }

 

 

Android 的布局有 MATCH_PARENT 和 WRAP_CONTENT, windows phone 下更简单,这使得在 Android 和 WP 下不用关心空间大小的分配。

但是在 ios 下有一点麻烦,UIScrollView 的 子视图需分配 Frame, 还需要计算好 ContentSize。但是控件加载的时候,空间和大小都还没有分配, 当然无法给子视图分配 Frame, 同理 ContentSize 也无法计算。

无奈只得在 Render 的 OnElementChanged 方法中,SetNativeControl 之后,调用 SizeToFit 方法,已使 GetDesiredSize 可以被触发,并将分配的大小传给 UIScrollView

 

1         public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) {
2             this.Control.UpdateLayout(widthConstraint, heightConstraint);
3             return UIViewExtensions.GetSizeRequest(this.NativeView, widthConstraint, heightConstraint, 44.0, 44.0);
4         }

 

在 UpdateLayout 方法中, 对 UIScrollView 的 Frame 进行调整, 然后强制重新布局 (LayoutSubviews 方法会被调用)。

1         public void UpdateLayout(double width, double height) {
2             this.Frame = new CGRect(0, 0, width, height);
3             this.PageControl.Frame = new CGRect(0, height - 20, width, 20);
4             //this.BringSubviewToFront(this.PageControl);
5             this.SetNeedsLayout();
6         }

 

 模拟器的效果就是上面的效果图, 但是在真机调试的时候,编译阶段报如下错误:

错误 30 error MT1007: Failed to launch the application ‘XXX‘ on the device ‘“XXX‘: Look for
earlier warnings returned: 0x454. You can still launch the application manually by tapping on it. Xamarin.iOS
Extension 0 0

手动点击安装到真机的APP, 无法运行。 这个应该是 Xamarin 的 Bug, 和代码无关,改天换个低版本的 Xamarin 在试。

-----------------------------

OK 完。

谢谢捧场。

FlipView For Xamarin.Form 之 IOS

标签:

原文地址:http://www.cnblogs.com/xling/p/4909933.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!