| | |
| | | { |
| | | readonly MyHorizontalPages iosUIScrolView; |
| | | |
| | | //readonly UIPageControl iosUIPageControl; |
| | | |
| | | |
| | | /// <summary> |
| | | /// 页面变化事件 |
| | | /// </summary> |
| | | public Action<HorizontalPages,int> PageChange; |
| | | public Action<HorizontalPages, int> PageChange; |
| | | |
| | | /// <summary> |
| | | /// 开始滑动事件 |
| | | /// </summary> |
| | | public Action StartScrollAction; |
| | | /// <summary> |
| | | /// 结束滑动事件 |
| | | /// </summary> |
| | | public Action EndScrollAction ; |
| | | |
| | | /// <summary> |
| | | /// 没有更多提示Action,已经是最后一个 |
| | | /// </summary> |
| | | public Action NoMoreAction; |
| | | |
| | | //ImageView LeftImageView = new ImageView() { ImagePath = "RoomIcon/1.jpg" }; |
| | | //ImageView RightImageView = new ImageView() { ImagePath = "RoomIcon/2.jpg" }; |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | | /// </summary> |
| | | public HorizontalPages() |
| | | { |
| | | viewGroup = new UIView(); |
| | | iosUIScrolView = new MyHorizontalPages(this) { }; |
| | | iosUIScrolView.Bounces = false; |
| | | InitMyHorizontalPagesEvent(); |
| | | realViewGroup = iosUIScrolView; |
| | | //启动翻页功能 |
| | | //iosUIScrolView.PagingEnabled = true; |
| | | iosUIScrolView.ShowsHorizontalScrollIndicator = false; |
| | | viewGroup.AddSubview(iosUIScrolView); |
| | | pagePadding = Application.GetRealWidth(50); |
| | | rowPadding = Application.GetRealWidth(100); |
| | | mTCBJ = Application.GetRealWidth(50); |
| | | |
| | | } |
| | | |
| | | ImageView LeftImageView; |
| | | ImageView RightImageView; |
| | | /// <summary> |
| | | /// 是否设置了虚假背景View 设置了才显示 |
| | | /// </summary> |
| | | bool IsSetLeftAndRightImageView = false; |
| | | /// <summary> |
| | | /// 设置控制最左和最右2边,填充的假背景View,不设置不显示,需要在AddChidren 前调用该方法 |
| | | /// </summary> |
| | | /// <param name="mLeftImageView"></param> |
| | | /// <param name="mRightImageView"></param> |
| | | public void SetLeftAndRightImageView(ImageView mLeftImageView, ImageView mRightImageView) |
| | | { |
| | | if (mLeftImageView == null) return; |
| | | |
| | | if (mRightImageView == null) return; |
| | | |
| | | //设置之前先清空一次 |
| | | foreach (var view in iosUIScrolView.Subviews) |
| | | { |
| | | view.RemoveFromSuperview(); |
| | | } |
| | | |
| | | LeftImageView = mLeftImageView; |
| | | iosUIScrolView.AddSubview(LeftImageView.RealView); |
| | | LeftImageView.Parent = this; |
| | | LeftImageView.Refresh(); |
| | | |
| | | RightImageView = mRightImageView; |
| | | iosUIScrolView.AddSubview(RightImageView.RealView); |
| | | RightImageView.Parent = this; |
| | | RightImageView.Refresh(); |
| | | |
| | | IsSetLeftAndRightImageView = true; |
| | | |
| | | } |
| | | |
| | | bool isNoMore; |
| | | bool isStart; |
| | | int mTouchSlop = 20; |
| | | nfloat beforeXScrollX; |
| | | nfloat moveX; |
| | | void InitMyHorizontalPagesEvent() |
| | | { |
| | | |
| | | |
| | | iosUIScrolView.Scrolled += (s, e) => |
| | | { |
| | | //Shared.HDLUtils.WriteLine($"HorizontalPages Scrolled ContentOffsetX:{iosUIScrolView.ContentOffset.X}"); |
| | | moveX = iosUIScrolView.ContentOffset.X - beforeXScrollX; |
| | | RefreshPageView(); |
| | | |
| | | if (mTouchSlop < Math.Abs(moveX)) |
| | | { |
| | | if (!isStart) |
| | | { |
| | | |
| | | //当前索引为,不是第一个或者最后一个,滑动距离大于触发距离并且没执行过则 执行一次StartScrollAction |
| | | if ((moveX > 0 && PageIndex < ChildrenCount - 1) || (moveX < 0 && PageIndex > 0)) |
| | | { |
| | | isStart = true; |
| | | StartScrollAction?.Invoke(); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | if (!isNoMore && !bSendPageChange) |
| | | { |
| | | //当前索引为第一个或者最后一个,滑动距离大于触发距离、没执行过、PageIndex没变化、则执行一次NoMoreAction |
| | | if ((moveX > 0 && PageIndex == ChildrenCount - 1 && iosUIScrolView.ContentOffset.X > iosUIScrolView.ContentSize.Width - iosUIScrolView.Frame.Width) || (moveX < 0 && PageIndex == 0 && iosUIScrolView.ContentOffset.X < 0)) |
| | | { |
| | | isNoMore = true; |
| | | NoMoreAction?.Invoke(); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | }; |
| | | |
| | | iosUIScrolView.DraggingStarted += (sender, e) => |
| | | { |
| | | //Shared.HDLUtils.WriteLine("HorizontalPages DraggingStarted"); |
| | | SetIsScrolling(true); |
| | | beforeXScrollX = iosUIScrolView.ContentOffset.X; |
| | | isStart = false; |
| | | isNoMore = false; |
| | | //StartScrollAction?.Invoke(); |
| | | }; |
| | | |
| | | iosUIScrolView.DecelerationStarted += (s, e) => |
| | | { |
| | | GetMovePageIndex(); |
| | | |
| | | }; |
| | | |
| | | iosUIScrolView.DecelerationEnded += (s, e) => |
| | | { |
| | | |
| | | if (!bSendPageChange && (PageIndex == ChildrenCount - 1 || PageIndex == 0 )) { |
| | | //当前索引为,第一个或者最后一个,并且之前执行过开始Action |
| | | SendEndScrollAction(); |
| | | |
| | | |
| | | } |
| | | |
| | | }; |
| | | |
| | | iosUIScrolView.DraggingEnded += (s, e) => |
| | | { |
| | | if (!e.Decelerate) |
| | | { |
| | | GetMovePageIndex(); |
| | | } |
| | | }; |
| | | |
| | | iosUIScrolView.ScrollAnimationEnded += (s, e) => |
| | | { |
| | | //Shared.HDLUtils.WriteLine("HorizontalPages ScrollAnimationEnded"); |
| | | SendIfPageChange(); |
| | | SetIsScrolling(false); |
| | | }; |
| | | } |
| | | |
| | | |
| | | private void GetMovePageIndex() |
| | | { |
| | | |
| | | if (mTouchSlop < Math.Abs(moveX)) |
| | | { |
| | | if (moveX < 0) |
| | | { |
| | | PageIndex -= 1; |
| | | } |
| | | else if (moveX > 0) |
| | | { |
| | | PageIndex += 1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | PageIndex = PageIndex; |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | //两个Page界面之间的距离 |
| | | int pagePadding; |
| | | /// <summary> |
| | | /// 界面之间的边距 |
| | | /// </summary> |
| | | public int JMBJ |
| | | { |
| | | get |
| | | { |
| | | return pagePadding; |
| | | } |
| | | set |
| | | { |
| | | pagePadding = value; |
| | | rowPadding = mTCBJ + pagePadding; |
| | | RefreshScrollWidth(); |
| | | ReLocation(); |
| | | } |
| | | } |
| | | |
| | | //page的与手机屏幕的边距 = 突出宽度 + 两个Page之间的距离 |
| | | int rowPadding; |
| | | /// <summary> |
| | | /// 突出宽度 |
| | | /// </summary> |
| | | int mTCBJ; |
| | | public int TCBJ |
| | | { |
| | | get |
| | | { |
| | | return mTCBJ; |
| | | } |
| | | set |
| | | { |
| | | mTCBJ = value; |
| | | rowPadding = mTCBJ + pagePadding; |
| | | RefreshScrollWidth(); |
| | | ReLocation(); |
| | | } |
| | | } |
| | | |
| | | int mScrollWidth; |
| | | int mPageWidth; |
| | | private void RefreshScrollWidth() |
| | | { |
| | | mScrollWidth = (int)this.RealView.Frame.Width - 2 * rowPadding + pagePadding; |
| | | mPageWidth = (int)this.RealView.Frame.Width - 2 * rowPadding; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 自动计算刷新所有View的高度,实现缩放效果 |
| | | /// </summary> |
| | | private void RefreshPageView() |
| | | { |
| | | //RefreshView(); |
| | | //RefreshViewWithTransform3D(); |
| | | //RefreshViewWithChangeHeight(); |
| | | RefreshViewWithChangeHeightNew(); |
| | | //RefreshViewWithChangeHeightSF(); |
| | | } |
| | | |
| | | //********************Transform3D 旋转效果方法********************** |
| | | //默认25度 |
| | | nfloat transformAngle = (nfloat)(25 * Math.PI / 180.0); |
| | | //旋转角度 |
| | | public int TransformAngle |
| | | { |
| | | set |
| | | { |
| | | transformAngle = (nfloat)(value * Math.PI / 180.0); |
| | | } |
| | | } |
| | | |
| | | ///// <summary> |
| | | ///// 旋转效果 |
| | | ///// </summary> |
| | | //public void RefreshViewWithTransform3D() |
| | | //{ |
| | | // if (ChildrenCount <= 0) return; |
| | | |
| | | // if (PageIndex > ChildrenCount - 1) |
| | | // { |
| | | // PageIndex = ChildrenCount - 1; |
| | | // } |
| | | |
| | | // // - 单位矩阵 |
| | | // CATransform3D transform = CATransform3D.Identity; |
| | | // // - 增加透视效果 |
| | | // transform.m34 = (nfloat)(-1.0 / 500); |
| | | // var mRotate = transform.Rotate(0, 0f, 1f, 0f); |
| | | // iosUIScrolView.Subviews[PageIndex].Layer.Transform = mRotate; |
| | | |
| | | |
| | | // //判断PageIndex 前后是否有view,并旋转 |
| | | // if (PageIndex - 1 >= 0) |
| | | // { |
| | | // var mRotate1 = transform.Rotate(transformAngle, 0f, 1f, 0f); |
| | | // iosUIScrolView.Subviews[PageIndex - 1].Layer.Transform = mRotate1; |
| | | // } |
| | | |
| | | // if (PageIndex <= ChildrenCount - 2) |
| | | // { |
| | | // var mRotate2 = transform.Rotate(-1 * transformAngle, 0f, 1f, 0f); |
| | | // iosUIScrolView.Subviews[PageIndex + 1].Layer.Transform = mRotate2; |
| | | // } |
| | | |
| | | |
| | | |
| | | |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// 刷新最大距离值 |
| | | /// </summary> |
| | | double MaxDistance; |
| | | |
| | | |
| | | private void RefreshViewWithChangeHeight() |
| | | { |
| | | if (ChildrenCount <= 0) return; |
| | | |
| | | if (PageIndex > ChildrenCount - 1) |
| | | { |
| | | PageIndex = ChildrenCount - 1; |
| | | } |
| | | |
| | | MaxDistance = Width - 2 * TCBJ - JMBJ; |
| | | double centerX = iosUIScrolView.ContentOffset.X + iosUIScrolView.Frame.Width * 0.5; |
| | | |
| | | foreach (UIView mSubview in iosUIScrolView.Subviews) |
| | | { |
| | | |
| | | double distance = Math.Abs(mSubview.Center.X - centerX); |
| | | var HH = 0; |
| | | if (distance <= 0) |
| | | { |
| | | HH = 0; |
| | | } |
| | | else if (distance >= MaxDistance) |
| | | { |
| | | HH = JMBJ; |
| | | } |
| | | else |
| | | { |
| | | HH = (int)((distance / MaxDistance) * JMBJ); |
| | | |
| | | } |
| | | var mFrame = mSubview.Frame; |
| | | mFrame.Height = Height - HH * 2; |
| | | mFrame.Y = HH; |
| | | mSubview.Frame = mFrame; |
| | | |
| | | //mSubview.MaskView |
| | | |
| | | |
| | | //double distance = Math.Abs(mSubview.Center.X - centerX); |
| | | //double factor = 0.01; |
| | | //float scale = (float)(1.0 / (1 + distance * factor)); |
| | | |
| | | ////var mFrame = mSubview.Frame; |
| | | ////mFrame.Height = Height * scale; |
| | | ////mFrame.Y = (Height - mFrame.Height) / 2; |
| | | ////mSubview.Frame = mFrame; |
| | | |
| | | //var mFrame = mSubview.Frame; |
| | | //var HH = (int)(MaxChangeHeight - MaxChangeHeight * scale); |
| | | //mFrame.Height = Height - HH; |
| | | //mFrame.Y = HH / 2; |
| | | //mSubview.Frame = mFrame; |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 同时刷新子view 和ImageView的高度,暂时解决底部圆角失效问题 |
| | | /// </summary> |
| | | /// <param name="mView"></param> |
| | | /// <param name="height"></param> |
| | | void RefreshSubviewHeight(View mView, nfloat height) |
| | | { |
| | | try |
| | | { |
| | | if (mView is ViewGroup) |
| | | { |
| | | var tempViewGroup = (ViewGroup)mView; |
| | | for (int i = 0; i < tempViewGroup.ChildrenCount; i++) |
| | | { |
| | | if (tempViewGroup.GetChildren(i) is ViewGroup) |
| | | { |
| | | var tempViewGroup2 = (ViewGroup)tempViewGroup.GetChildren(i); |
| | | for (int j = 0; j < tempViewGroup2.ChildrenCount; j++) |
| | | { |
| | | if (tempViewGroup2.GetChildren(j) is ImageView && tempViewGroup2.GetChildren(j).Tag.ToString() == "R") |
| | | { |
| | | |
| | | tempViewGroup2.GetChildren(j).Height = (int)height; |
| | | break; |
| | | } |
| | | } |
| | | if (tempViewGroup2.Tag.ToString() == "R") |
| | | { |
| | | tempViewGroup2.Height = (int)height; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | catch { } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 计算滑动缩放高度的方法 |
| | | /// </summary> |
| | | private void RefreshViewWithChangeHeightNew() |
| | | { |
| | | if (ChildrenCount <= 0) return; |
| | | |
| | | if (PageIndex > ChildrenCount - 1) |
| | | { |
| | | PageIndex = ChildrenCount - 1; |
| | | } |
| | | |
| | | MaxDistance = Width - 2 * TCBJ - JMBJ; |
| | | double centerX = iosUIScrolView.ContentOffset.X + iosUIScrolView.Frame.Width * 0.5; |
| | | |
| | | for (int i = 0; i < ChildrenCount; i++) |
| | | { |
| | | var mSubview = GetChildren(i).RealView; |
| | | var view = GetChildren(i); |
| | | double distance = Math.Abs(mSubview.Center.X - centerX); |
| | | var HH = 0; |
| | | if (distance <= 0) |
| | | { |
| | | HH = 0; |
| | | } |
| | | else if (distance >= MaxDistance) |
| | | { |
| | | HH = JMBJ; |
| | | } |
| | | else |
| | | { |
| | | HH = (int)((distance / MaxDistance) * JMBJ); |
| | | |
| | | } |
| | | var mFrame = mSubview.Frame; |
| | | mFrame.Height = Height - HH * 2; |
| | | mFrame.Y = HH; |
| | | mSubview.Frame = mFrame; |
| | | |
| | | RefreshSubviewHeight(view, mFrame.Height); |
| | | } |
| | | } |
| | | |
| | | //private void RefreshViewWithChangeHeightSF() |
| | | //{ |
| | | // if (ChildrenCount <= 0) return; |
| | | |
| | | // if (PageIndex > ChildrenCount - 1) |
| | | // { |
| | | // PageIndex = ChildrenCount - 1; |
| | | // } |
| | | |
| | | // MaxDistance = Width - 2 * TCBJ - JMBJ; |
| | | // double centerX = iosUIScrolView.ContentOffset.X + iosUIScrolView.Frame.Width * 0.5; |
| | | |
| | | // foreach (UIView mSubview in iosUIScrolView.Subviews) |
| | | // { |
| | | |
| | | // double distance = Math.Abs(mSubview.Center.X - centerX); |
| | | // nfloat HH = 1; |
| | | // if (distance <= 0) |
| | | // { |
| | | // mSubview.Transform = CGAffineTransform.MakeScale(1.0f, 1.0f); |
| | | // } |
| | | // else if (distance >= MaxDistance) |
| | | // { |
| | | // mSubview.Transform = CGAffineTransform.MakeScale(1.0f, 0.8f); |
| | | // } |
| | | // else |
| | | // { |
| | | // HH = (nfloat)((1-distance / MaxDistance) * 0.2f) + 0.8f; |
| | | // mSubview.Transform = CGAffineTransform.MakeScale(1.0f, 0.8f); |
| | | // } |
| | | |
| | | // } |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// 是否允许滑动 |
| | | /// </summary> |
| | | /// <value><c>true</c> if scroll enabled; otherwise, <c>false</c>.</value> |
| | | public bool ScrollEnabled |
| | | { |
| | | get |
| | | { |
| | | return (iosUIScrolView as MyHorizontalPages).ScrollEnabled; |
| | | } |
| | | set |
| | | { |
| | | (iosUIScrolView as MyHorizontalPages).ScrollEnabled = value; |
| | | } |
| | | } |
| | | |
| | | int pageIndex; |
| | | /// <summary> |
| | | /// 设置或者获取当前的界面索引 |
| | | /// </summary> |
| | | /// <value>The index of the page.</value> |
| | | public int PageIndex |
| | | { |
| | | get |
| | | { |
| | | return pageIndex; |
| | | } |
| | | set |
| | | { |
| | | if (value < 0 || ChildrenCount <= value) |
| | | { |
| | | |
| | | return; |
| | | } |
| | | int beforePageIndex = pageIndex; |
| | | pageIndex = value; |
| | | if (!IsCanRefresh) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var viewSize = iosUIScrolView.Frame.Size; |
| | | |
| | | RefreshPageView(); |
| | | var rect = new CGRect(pageIndex * viewSize.Width, 0, viewSize.Width, viewSize.Height); |
| | | if (pageIndex != 0) |
| | | { |
| | | var frame = GetChildren(pageIndex).RealView.Frame; |
| | | var w = frame.X - rowPadding; |
| | | |
| | | rect = new CGRect(w, 0, viewSize.Width, viewSize.Height); |
| | | //Shared.HDLUtils.WriteLine($"CGRect xx-------{w}"); |
| | | } |
| | | |
| | | //Shared.HDLUtils.WriteLine($"pageIndex xx-------{pageIndex}"); |
| | | iosUIScrolView.ScrollRectToVisible(rect, true); |
| | | |
| | | if (beforePageIndex != pageIndex) |
| | | { |
| | | bSendPageChange = true;//发送改变标志 |
| | | if (!isStart) |
| | | { |
| | | isStart = true; |
| | | StartScrollAction?.Invoke(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | SendEndScrollAction(); |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断是否需要发送结束滑动事件 |
| | | /// </summary> |
| | | void SendEndScrollAction() { |
| | | if (isStart) |
| | | { |
| | | isStart = false; |
| | | EndScrollAction?.Invoke(); |
| | | } |
| | | } |
| | | |
| | | bool bSendPageChange = false; |
| | | /// <summary> |
| | | /// 判断是否要发送改变事件 |
| | | /// </summary> |
| | | private void SendIfPageChange() |
| | | { |
| | | if (bSendPageChange) |
| | | { |
| | | bSendPageChange = false; |
| | | PageChange?.Invoke(this, pageIndex); |
| | | } |
| | | |
| | | //判断是否需要发送结束滑动事件 |
| | | SendEndScrollAction(); |
| | | } |
| | | |
| | | bool isScrolling; |
| | | /// <summary> |
| | | /// 是否正在滑动 |
| | | /// </summary> |
| | | public bool ISScrolling |
| | | { |
| | | get |
| | | { |
| | | return isScrolling; |
| | | } |
| | | } |
| | | |
| | | private void SetIsScrolling(bool bSctolling) |
| | | { |
| | | if (isScrolling == bSctolling) return; |
| | | |
| | | Shared.HDLUtils.WriteLine($"HorizontalPages StartScroll: {bSctolling}"); |
| | | isScrolling = bSctolling; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否正在滑动 |
| | | /// </summary> |
| | | /// <value><c>true</c> if decelerating; otherwise, <c>false</c>.</value> |
| | | public bool Decelerating |
| | | { |
| | | get |
| | | { |
| | | return iosUIScrolView.Decelerating; |
| | | } |
| | | } |
| | | |
| | | //public void DelayPageChange() |
| | | //{ |
| | | // PageChange?.Invoke(this, pageIndex); |
| | | |
| | | // //new System.Threading.Thread(async () => |
| | | // //{ |
| | | // // System.Threading.Thread.Sleep(500); |
| | | // // Application.RunOnMainThread(() => |
| | | // // { |
| | | // // PageChange?.Invoke(this, pageIndex); |
| | | // // }); |
| | | // //}) |
| | | // //{ IsBackground = true }.Start(); |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// 增加子控件 |
| | | /// </summary> |
| | | /// <param name="view">View.</param> |
| | | public override void AddChidren(View view) |
| | | { |
| | | base.AddChidren(view); |
| | | ReLocation(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重新排位置及设备内容大小 |
| | | /// </summary> |
| | | public virtual void ReLocation() |
| | | { |
| | | try |
| | | { |
| | | if (ChildrenCount == 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | |
| | | var frame0 = GetChildren(0).RealView.Frame; |
| | | frame0.X = rowPadding; |
| | | frame0.Y = 0; |
| | | frame0.Width = mPageWidth; |
| | | frame0.Height = iosUIScrolView.Frame.Height; |
| | | GetChildren(0).RealView.Frame = frame0; |
| | | |
| | | |
| | | |
| | | for (int i = 1; i < ChildrenCount; i++) |
| | | { |
| | | var frame = GetChildren(i).RealView.Frame; |
| | | |
| | | frame.Width = mPageWidth; |
| | | frame.Height = iosUIScrolView.Frame.Height; |
| | | frame.Y = 0; |
| | | //frame.X = iosUIScrolView.Subviews[i - 1].Frame.Right + pagePadding; |
| | | frame.X = rowPadding + (mPageWidth + pagePadding) * i; |
| | | GetChildren(i).RealView.Frame = frame; |
| | | } |
| | | iosUIScrolView.ContentSize = new CoreGraphics.CGSize(GetChildren(ChildrenCount - 1).RealView.Frame.Right + rowPadding, iosUIScrolView.Frame.Height); |
| | | |
| | | //iosUIScrolView.ContentSize = new CoreGraphics.CGSize(iosUIScrolView.Subviews[ChildrenCount - 1].Frame.Right + rowPadding, iosUIScrolView.Frame.Height); |
| | | |
| | | if (IsSetLeftAndRightImageView) |
| | | { |
| | | var leftFrame = iosUIScrolView.Subviews[0].Frame; |
| | | leftFrame.X = TCBJ - mPageWidth; |
| | | leftFrame.Y = JMBJ; |
| | | leftFrame.Width = mPageWidth; |
| | | leftFrame.Height = Height - JMBJ * 2; |
| | | iosUIScrolView.Subviews[0].Frame = leftFrame; |
| | | |
| | | |
| | | var rightFrame = iosUIScrolView.Subviews[1].Frame; |
| | | rightFrame.X = rowPadding + (mPageWidth + pagePadding) * (ChildrenCount); |
| | | rightFrame.Y = JMBJ; |
| | | rightFrame.Width = mPageWidth; |
| | | rightFrame.Height = Height - JMBJ * 2; |
| | | iosUIScrolView.Subviews[1].Frame = rightFrame; |
| | | } |
| | | |
| | | RefreshPageView(); |
| | | } |
| | | catch { } |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 控件宽度 |
| | | /// </summary> |
| | | /// <value>The width.</value> |
| | | public override int Width |
| | | { |
| | | get |
| | | { |
| | | return base.Width; |
| | | } |
| | | set |
| | | { |
| | | base.Width = value; |
| | | |
| | | if (!IsCanRefresh) |
| | | return; |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 控件的高度 |
| | | /// </summary> |
| | | /// <value>The height.</value> |
| | | public override int Height |
| | | { |
| | | get |
| | | { |
| | | return base.Height; |
| | | } |
| | | set |
| | | { |
| | | base.Height = value; |
| | | if (!IsCanRefresh) |
| | | return; |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Bounces |
| | | /// </summary> |
| | | public bool Bounces |
| | | { |
| | | get |
| | | { |
| | | return iosUIScrolView.Bounces; |
| | | } |
| | | set |
| | | { |
| | | iosUIScrolView.Bounces = value; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 移除当前控件 |
| | | /// </summary> |
| | | /// <param name="view">View.</param> |
| | | internal override void Remove(View view) |
| | | { |
| | | base.Remove(view); |
| | | ReLocation(); |
| | | |
| | | if (PageIndex > ChildrenCount - 1) |
| | | { |
| | | PageIndex = ChildrenCount - 1; |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除所有的控件 |
| | | /// </summary> |
| | | public override void RemoveAll() |
| | | { |
| | | base.RemoveAll(); |
| | | ReLocation(); |
| | | PageIndex = 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据索引移除控件 |
| | | /// </summary> |
| | | /// <param name="index">Index.</param> |
| | | public override void RemoveAt(int index) |
| | | { |
| | | if (viewList.Count - 1 < index || index < 0) |
| | | { |
| | | return; |
| | | } |
| | | Remove(viewList[index]); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 垂直方向滚动视图 |
| | | /// </summary> |
| | | class MyHorizontalPages : UIScrollView |
| | | { |
| | | nfloat beforeXScrollX; |
| | | nfloat moveX; |
| | | |
| | | [Weak] HorizontalPages HorizontalPages; |
| | | //nfloat mLastX, mLastY, deltaX; |
| | | [Weak] HorizontalPages HorizontalPages; |
| | | public MyHorizontalPages(HorizontalPages HorizontalPages) |
| | | { |
| | | |
| | | this.HorizontalPages = HorizontalPages; |
| | | //this.ScrollEnabled = false; |
| | | Scrolled += (s, e) => |
| | | { |
| | | moveX = this.ContentOffset.X - beforeXScrollX; |
| | | }; |
| | | |
| | | DraggingStarted += (sender, e) => |
| | | { |
| | | beforeXScrollX = this.ContentOffset.X; |
| | | }; |
| | | |
| | | DecelerationStarted += (s, e) => |
| | | { |
| | | //var tempUIScrolView = s as MyHorizontalPages; |
| | | ////获取当前界面的索引 |
| | | ////System.Console.WriteLine($"DecelerationStarted-------{tempUIScrolView.ContentOffset.X}"); |
| | | //var tempPageIndex = Convert.ToInt32(tempUIScrolView.ContentOffset.X / (this.HorizontalPages.mScrollWidth)); |
| | | //this.HorizontalPages.PageIndex = tempPageIndex; |
| | | GetMovePageIndex(); |
| | | |
| | | }; |
| | | |
| | | //DecelerationEnded += (s, e) => |
| | | //{ |
| | | // Console.WriteLine("HorizontalPages DecelerationEnded"); |
| | | |
| | | //}; |
| | | |
| | | DraggingEnded += (s, e) => |
| | | { |
| | | |
| | | var tempUIScrolView = s as MyHorizontalPages; |
| | | if (!e.Decelerate) |
| | | { |
| | | GetMovePageIndex(); |
| | | ////System.Console.WriteLine($"DraggingEnded-------{tempUIScrolView.ContentOffset.X}"); |
| | | //var tempPageIndex = Convert.ToInt32(tempUIScrolView.ContentOffset.X / (this.HorizontalPages.mScrollWidth)); |
| | | //this.HorizontalPages.PageIndex = tempPageIndex; |
| | | } |
| | | }; |
| | | } |
| | | |
| | | private void GetMovePageIndex() { |
| | | ///// <summary> |
| | | ///// 点击开始 |
| | | ///// </summary> |
| | | ///// <param name="touches">Touches.</param> |
| | | ///// <param name="evt">Evt.</param> |
| | | //public override void TouchesBegan(NSSet touches, UIEvent evt) |
| | | //{ |
| | | |
| | | if (mTouchSlop < Math.Abs(moveX)) |
| | | { |
| | | if (moveX < 0) |
| | | { |
| | | this.HorizontalPages.PageIndex -= 1; |
| | | } |
| | | else if (moveX > 0) |
| | | { |
| | | this.HorizontalPages.PageIndex += 1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | this.HorizontalPages.PageIndex = this.HorizontalPages.PageIndex; |
| | | } |
| | | // HorizontalPages?.TouchEvent(EventActions.Down, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | |
| | | } |
| | | //} |
| | | |
| | | //int mTouchSlop = 20; |
| | | //bool bMove; |
| | | ///// <summary> |
| | | ///// 移动 |
| | | ///// </summary> |
| | | ///// <param name="touches">Touches.</param> |
| | | ///// <param name="evt">Evt.</param> |
| | | //public override void TouchesMoved(NSSet touches, UIEvent evt) |
| | | //{ |
| | | // HorizontalPages?.TouchEvent(EventActions.Move, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | |
| | | /// <summary> |
| | | /// 点击开始 |
| | | /// </summary> |
| | | /// <param name="touches">Touches.</param> |
| | | /// <param name="evt">Evt.</param> |
| | | public override void TouchesBegan(NSSet touches, UIEvent evt) |
| | | { |
| | | |
| | | HorizontalPages?.TouchEvent(EventActions.Down, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | //} |
| | | ///// <summary> |
| | | ///// 点击弹起 |
| | | ///// </summary> |
| | | ///// <param name="touches">Touches.</param> |
| | | ///// <param name="evt">Evt.</param> |
| | | //public override void TouchesEnded(NSSet touches, UIEvent evt) |
| | | //{ |
| | | // HorizontalPages?.TouchEvent(EventActions.Up, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | //} |
| | | |
| | | //CGPoint point = (touches.AnyObject as UITouch).LocationInView(this); |
| | | ////记录点击的最新X坐标 |
| | | //mLastX = point.X; |
| | | //bMove = false; |
| | | //System.Console.WriteLine($"TouchesBegan-------{mLastX}"); |
| | | } |
| | | |
| | | int mTouchSlop = 20; |
| | | bool bMove; |
| | | /// <summary> |
| | | /// 移动 |
| | | /// </summary> |
| | | /// <param name="touches">Touches.</param> |
| | | /// <param name="evt">Evt.</param> |
| | | public override void TouchesMoved(NSSet touches, UIEvent evt) |
| | | { |
| | | |
| | | |
| | | HorizontalPages?.TouchEvent(EventActions.Move, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | |
| | | //CGPoint point = (touches.AnyObject as UITouch).LocationInView(this); |
| | | //deltaX = point.X - mLastX; |
| | | //if (Math.Abs(deltaX) >= mTouchSlop) { |
| | | // bMove = true; |
| | | //} |
| | | //System.Console.WriteLine($"deltaX-------{deltaX}"); |
| | | |
| | | } |
| | | /// <summary> |
| | | /// 点击弹起 |
| | | /// </summary> |
| | | /// <param name="touches">Touches.</param> |
| | | /// <param name="evt">Evt.</param> |
| | | public override void TouchesEnded(NSSet touches, UIEvent evt) |
| | | { |
| | | HorizontalPages?.TouchEvent(EventActions.Up, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | |
| | | //if (bMove) |
| | | //{ |
| | | // if (deltaX < 0)//左滑 |
| | | // { |
| | | // this.HorizontalPages.PageIndex--; |
| | | // } |
| | | // else |
| | | // { |
| | | // this.HorizontalPages.PageIndex++; |
| | | |
| | | // } |
| | | //} |
| | | } |
| | | |
| | | public override void TouchesCancelled(NSSet touches, UIEvent evt) |
| | | { |
| | | HorizontalPages?.TouchEvent(EventActions.Cancel, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | } |
| | | //public override void TouchesCancelled(NSSet touches, UIEvent evt) |
| | | //{ |
| | | // HorizontalPages?.TouchEvent(EventActions.Cancel, (touches.AnyObject as UITouch).LocationInView(this)); |
| | | //} |
| | | /// <summary> |
| | | /// 框架默认加了两个UIImageView ,这样可以去掉默认添加 |
| | | /// </summary> |
| | |
| | | base.AddSubview(view); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | | /// </summary> |
| | | public HorizontalPages() |
| | | { |
| | | viewGroup = new UIView(); |
| | | iosUIScrolView = new MyHorizontalPages(this) { }; |
| | | realViewGroup = iosUIScrolView; |
| | | //启动翻页功能 |
| | | //iosUIScrolView.PagingEnabled = true; |
| | | iosUIScrolView.ShowsHorizontalScrollIndicator = false; |
| | | viewGroup.AddSubview(iosUIScrolView); |
| | | _PagePadding = Application.GetRealWidth(50); |
| | | _RowPadding = Application.GetRealWidth(100); |
| | | _TCBJ = Application.GetRealWidth(50); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | // //两个Page之间的距离 |
| | | //int _PagePadding; |
| | | //public int PagePadding |
| | | //{ |
| | | // get |
| | | // { |
| | | // return _PagePadding; |
| | | // } |
| | | // set |
| | | // { |
| | | // _PagePadding = value; |
| | | // ReLocation(); |
| | | // } |
| | | //} |
| | | ////page的外边距 |
| | | //int _RowPadding; |
| | | //public int RowPadding |
| | | //{ |
| | | // get |
| | | // { |
| | | // return _RowPadding; |
| | | // } |
| | | // set |
| | | // { |
| | | // _RowPadding = value; |
| | | // ReLocation(); |
| | | // } |
| | | //} |
| | | /// <summary> |
| | | /// 突出宽度 |
| | | /// </summary> |
| | | //public int JMBJ |
| | | |
| | | |
| | | //两个Page界面之间的距离 |
| | | int _PagePadding; |
| | | /// <summary> |
| | | /// 界面之间的边距 |
| | | /// </summary> |
| | | public int JMBJ |
| | | { |
| | | get |
| | | { |
| | | return _PagePadding; |
| | | } |
| | | set |
| | | { |
| | | _PagePadding = value; |
| | | _RowPadding = _TCBJ + _PagePadding; |
| | | RefreshScrollWidth(); |
| | | ReLocation(); |
| | | } |
| | | } |
| | | |
| | | //page的与手机屏幕的边距 = 突出宽度 + 两个Page之间的距离 |
| | | int _RowPadding; |
| | | /// <summary> |
| | | /// 突出宽度 |
| | | /// </summary> |
| | | int _TCBJ; |
| | | public int TCBJ |
| | | { |
| | | get |
| | | { |
| | | return _TCBJ; |
| | | } |
| | | set |
| | | { |
| | | _TCBJ = value; |
| | | _RowPadding = _TCBJ + _PagePadding; |
| | | RefreshScrollWidth(); |
| | | ReLocation(); |
| | | } |
| | | } |
| | | |
| | | int mScrollWidth; |
| | | int mPageWidth; |
| | | private void RefreshScrollWidth() |
| | | { |
| | | mScrollWidth = (int)this.RealView.Frame.Width - 2 * _RowPadding + _PagePadding; |
| | | mPageWidth = (int)this.RealView.Frame.Width - 2 * _RowPadding; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | private void RefreshPageView() { |
| | | //RefreshView(); |
| | | RefreshViewWithTransform3D(); |
| | | } |
| | | |
| | | //********************Transform3D 旋转效果方法********************** |
| | | //默认25度 |
| | | nfloat transformAngle = (nfloat)(25 * Math.PI / 180.0); |
| | | //旋转角度 |
| | | public int TransformAngle |
| | | { |
| | | set |
| | | { |
| | | transformAngle = (nfloat)(value * Math.PI / 180.0); |
| | | } |
| | | } |
| | | |
| | | // |
| | | public void RefreshViewWithTransform3D() |
| | | { |
| | | if (iosUIScrolView.Subviews.Length <= 0) return; |
| | | |
| | | if (PageIndex > iosUIScrolView.Subviews.Length - 1) |
| | | { |
| | | PageIndex = iosUIScrolView.Subviews.Length - 1; |
| | | } |
| | | |
| | | // - 单位矩阵 |
| | | CATransform3D transform = CATransform3D.Identity; |
| | | // - 增加透视效果 |
| | | transform.m34 = (nfloat)(-1.0 / 500); |
| | | var mRotate = transform.Rotate(0, 0f, 1f, 0f); |
| | | iosUIScrolView.Subviews[PageIndex].Layer.Transform = mRotate; |
| | | |
| | | |
| | | //判断PageIndex 前后是否有view,并旋转 |
| | | if (PageIndex - 1 >= 0) |
| | | { |
| | | var mRotate1 = transform.Rotate(transformAngle, 0f, 1f, 0f); |
| | | iosUIScrolView.Subviews[PageIndex - 1].Layer.Transform = mRotate1; |
| | | } |
| | | |
| | | if (PageIndex <= iosUIScrolView.Subviews.Length - 2) |
| | | { |
| | | var mRotate2 = transform.Rotate(-1 * transformAngle, 0f, 1f, 0f); |
| | | iosUIScrolView.Subviews[PageIndex + 1].Layer.Transform = mRotate2; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | int PaddingHeight = 20; |
| | | //********************普通高度改变方法********************** |
| | | private void RefreshView() |
| | | { |
| | | if (iosUIScrolView.Subviews.Length <= 0) return; |
| | | |
| | | if (PageIndex > iosUIScrolView.Subviews.Length - 1) |
| | | { |
| | | PageIndex = iosUIScrolView.Subviews.Length - 1; |
| | | } |
| | | |
| | | //System.Console.WriteLine($" tempPageIndex:{PageIndex}"); |
| | | if (PageIndex == 0) |
| | | { |
| | | var frame0 = iosUIScrolView.Subviews[0].Frame; |
| | | frame0.Height = iosUIScrolView.Frame.Height; |
| | | frame0.Y = 0; |
| | | iosUIScrolView.Subviews[0].Frame = frame0; |
| | | |
| | | if (iosUIScrolView.Subviews.Length > 1) |
| | | { |
| | | var frame1 = iosUIScrolView.Subviews[1].Frame; |
| | | frame1.Height = iosUIScrolView.Frame.Height - PaddingHeight; |
| | | frame1.Y = PaddingHeight/2; |
| | | iosUIScrolView.Subviews[1].Frame = frame1; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | else |
| | | { |
| | | var frame0 = iosUIScrolView.Subviews[PageIndex].Frame; |
| | | frame0.Height = iosUIScrolView.Frame.Height; |
| | | frame0.Y = 0; |
| | | iosUIScrolView.Subviews[PageIndex].Frame = frame0; |
| | | |
| | | var frame = iosUIScrolView.Subviews[PageIndex - 1].Frame; |
| | | frame.Height = iosUIScrolView.Frame.Height - PaddingHeight; |
| | | frame.Y = PaddingHeight/2; |
| | | iosUIScrolView.Subviews[PageIndex - 1].Frame = frame; |
| | | if (PageIndex <= iosUIScrolView.Subviews.Length - 2) |
| | | { |
| | | var frame1 = iosUIScrolView.Subviews[PageIndex + 1].Frame; |
| | | frame1.Height = iosUIScrolView.Frame.Height - PaddingHeight; |
| | | frame1.Y = PaddingHeight/2; |
| | | iosUIScrolView.Subviews[PageIndex + 1].Frame = frame1; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 是否允许滑动 |
| | | /// </summary> |
| | | /// <value><c>true</c> if scroll enabled; otherwise, <c>false</c>.</value> |
| | | public bool ScrollEnabled |
| | | { |
| | | get |
| | | { |
| | | return (iosUIScrolView as MyHorizontalPages).ScrollEnabled; |
| | | } |
| | | set |
| | | { |
| | | (iosUIScrolView as MyHorizontalPages).ScrollEnabled = value; |
| | | } |
| | | } |
| | | |
| | | int pageIndex; |
| | | /// <summary> |
| | | /// 设置或者获取当前的界面索引 |
| | | /// </summary> |
| | | /// <value>The index of the page.</value> |
| | | public int PageIndex |
| | | { |
| | | get |
| | | { |
| | | return pageIndex; |
| | | } |
| | | set |
| | | { |
| | | if (value < 0 || ChildrenCount <= value) |
| | | { |
| | | return; |
| | | } |
| | | int beforePageIndex = pageIndex; |
| | | pageIndex = value; |
| | | if (!IsCanRefresh) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var viewSize = iosUIScrolView.Frame.Size; |
| | | |
| | | RefreshPageView(); |
| | | var rect = new CGRect(pageIndex * viewSize.Width, 0, viewSize.Width, viewSize.Height); |
| | | if (pageIndex != 0) { |
| | | var frame = iosUIScrolView.Subviews[pageIndex].Frame; |
| | | var w = frame.X - _RowPadding; |
| | | |
| | | rect = new CGRect(w, 0, viewSize.Width, viewSize.Height); |
| | | //System.Console.WriteLine($"CGRect xx-------{w}"); |
| | | } |
| | | |
| | | //System.Console.WriteLine($"pageIndex xx-------{pageIndex}"); |
| | | |
| | | //Console.WriteLine("HorizontalPages ScrollRectToVisible"); |
| | | iosUIScrolView.ScrollRectToVisible(rect, true); |
| | | |
| | | if (beforePageIndex != pageIndex) |
| | | { |
| | | //Console.WriteLine("HorizontalPages DelayPageChange"); |
| | | DelayPageChange(); |
| | | //PageChange?.Invoke(this, pageIndex); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public void DelayPageChange() |
| | | { |
| | | new System.Threading.Thread(async () => |
| | | { |
| | | System.Threading.Thread.Sleep(500); |
| | | Application.RunOnMainThread(() => |
| | | { |
| | | PageChange?.Invoke(this, pageIndex); |
| | | }); |
| | | }) |
| | | { IsBackground = true }.Start(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 增加子控件 |
| | | /// </summary> |
| | | /// <param name="view">View.</param> |
| | | public override void AddChidren(View view) |
| | | { |
| | | //var v = Application.AverageScale; |
| | | //var vv = Application.CurrentHeight; |
| | | //var dddd = Application.DesignWidth; |
| | | base.AddChidren(view); |
| | | ReLocation(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重新排位置及设备内容大小 |
| | | /// </summary> |
| | | public virtual void ReLocation() |
| | | { |
| | | if (iosUIScrolView.Subviews.Length == 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var frame0 = iosUIScrolView.Subviews[0].Frame; |
| | | frame0.X = _RowPadding; |
| | | frame0.Y = 0; |
| | | frame0.Width = mPageWidth; |
| | | frame0.Height = iosUIScrolView.Frame.Height; |
| | | iosUIScrolView.Subviews[0].Frame = frame0; |
| | | |
| | | |
| | | |
| | | for (int i = 1; i < iosUIScrolView.Subviews.Length; i++) |
| | | { |
| | | var frame = iosUIScrolView.Subviews[i].Frame; |
| | | |
| | | frame.Width = mPageWidth; |
| | | frame.Height = iosUIScrolView.Frame.Height; |
| | | frame.Y = 0; |
| | | //frame.X = iosUIScrolView.Subviews[i - 1].Frame.Right + _PagePadding; |
| | | frame.X = _RowPadding + (mPageWidth + _PagePadding)*i; |
| | | iosUIScrolView.Subviews[i].Frame = frame; |
| | | } |
| | | |
| | | iosUIScrolView.ContentSize = new CoreGraphics.CGSize(iosUIScrolView.Subviews[iosUIScrolView.Subviews.Length - 1].Frame.Right+_RowPadding, iosUIScrolView.Frame.Height); |
| | | RefreshPageView(); |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 控件宽度 |
| | | /// </summary> |
| | | /// <value>The width.</value> |
| | | public override int Width |
| | | { |
| | | get |
| | | { |
| | | return base.Width; |
| | | } |
| | | set |
| | | { |
| | | base.Width = value; |
| | | |
| | | if (!IsCanRefresh) |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 控件的高度 |
| | | /// </summary> |
| | | /// <value>The height.</value> |
| | | public override int Height |
| | | { |
| | | get |
| | | { |
| | | return base.Height; |
| | | } |
| | | set |
| | | { |
| | | base.Height = value; |
| | | if (!IsCanRefresh) |
| | | return; |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除当前控件 |
| | | /// </summary> |
| | | /// <param name="view">View.</param> |
| | | internal override void Remove(View view) |
| | | { |
| | | base.Remove(view); |
| | | ReLocation(); |
| | | |
| | | if (PageIndex > ChildrenCount - 1) |
| | | { |
| | | PageIndex = ChildrenCount - 1; |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除所有的控件 |
| | | /// </summary> |
| | | public override void RemoveAll() |
| | | { |
| | | base.RemoveAll(); |
| | | ReLocation(); |
| | | PageIndex = 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据索引移除控件 |
| | | /// </summary> |
| | | /// <param name="index">Index.</param> |
| | | public override void RemoveAt(int index) |
| | | { |
| | | if (viewList.Count - 1 < index || index < 0) |
| | | { |
| | | return; |
| | | } |
| | | Remove(viewList[index]); |
| | | } |
| | | } |
| | | } |
| | | |