using System; using UIKit; using System.IO; using Foundation; using CoreGraphics; using Shared.IO; namespace Shared { /// /// 位置布局 /// public class VerticalSeekBar : View { /// /// 滑块 /// UIButton btnThum = new UIButton(new CGRect(0, 0, 24, 24)) { Enabled = false }; /// /// 进度条颜色 /// UIButton btnProgressColor = new UIButton(new CGRect(0, 0, 1, 0)) { Enabled = false }; /// /// 背景进度条颜色 /// UIButton btnBackgroundColor = new UIButton(new CGRect(0, 0, 1, 0)) { Enabled = false }; MyVerticalSeekBar currentRealView; /// /// 构造函数 /// public VerticalSeekBar() { currentRealView = new MyVerticalSeekBar(this) { }; uiView = currentRealView; uiView.AddSubview(btnBackgroundColor); uiView.AddSubview(btnProgressColor); uiView.AddSubview(btnThum); } /// /// 生成圆形的滑动 /// /// The image with color. /// Color. UIImage createImageWithColor(UIColor color) { //设置长宽 CGRect rect = new CGRect(0.0f, 0.0f, btnThum.Frame.Width, btnThum.Frame.Width); UIGraphics.BeginImageContext(rect.Size); var context = UIGraphics.GetCurrentContext(); context.SetFillColor(color.CGColor); context.FillRect(rect); UIImage resultImage = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); // 开始一个Image的上下文 UIGraphics.BeginImageContextWithOptions(resultImage.Size, false, 0.0f); // 添加圆角 UIBezierPath.FromRoundedRect(rect, btnThum.Frame.Width / 2).AddClip(); // 绘制图片 resultImage.Draw(rect); // 接受绘制成功的图片 resultImage = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); return resultImage; } public override void Refresh() { base.Refresh(); ProgressColor = progressColor; BackgroundColor = backgroundColor; ThumbColor = thumbColor; Progress = progress; } /// /// 当前视图的高度 /// /// The height. public override int Height { get { return base.Height; } set { base.Height = value; if (!IsCanRefresh) { return; } var frameBackgroundColor = btnBackgroundColor.Frame; frameBackgroundColor.Height = base.Height; btnBackgroundColor.Frame = frameBackgroundColor; } } /// /// 当前视图的宽度 /// /// The width. public override int Width { get { return base.Width; } set { base.Width = value; if (!IsCanRefresh) { return; } var frameBtnFrame = btnThum.Frame; frameBtnFrame.X = (base.Width - btnThum.Frame.Width) / 2; btnThum.Frame = frameBtnFrame; var frameBackgroundColor = btnBackgroundColor.Frame; frameBackgroundColor.X = (base.Width - frameBackgroundColor.Width) / 2; btnBackgroundColor.Frame = frameBackgroundColor; var frameProgressColor = btnProgressColor.Frame; frameProgressColor.X = (base.Width - frameProgressColor.Width) / 2; btnProgressColor.Frame = frameProgressColor; } } DateTime dateTime; /// /// 进度变化事件 /// public Action ProgressChanged; int max = 100; /// /// 最大值 /// /// The max. public int Max { get { return max; } set { max = value; } } bool isCanScrolled = true; /// /// 是否允许滑动滑块 /// /// true if is can scrolled; otherwise, false. public bool IsCanScrolled { get { return isCanScrolled; } set { isCanScrolled = value; } } nfloat validHeight { get { return uiView.Frame.Height - btnThum.Frame.Height; } } //2019-08-29 改100毫秒 public int DelayTime = 100; //防止跳动,延时显示状态 DateTime delayDateTime = DateTime.MinValue; int progress; /// /// 当前进度 /// /// The progress. public int Progress { get { return (int)(Max * (validHeight - btnThum.Frame.Y) / validHeight); } set { progress = value; if (!IsCanRefresh) { return; } //发送命令后3000毫秒内不更新状态,防止跳动 if ((DateTime.Now - delayDateTime).TotalMilliseconds < DelayTime) { return; } if (Max < progress) { progress = Max; } var frameThum = btnThum.Frame; frameThum.Y = 1.0f*(Max - progress) / Max * validHeight; btnThum.Frame = frameThum; var frameProgress = btnProgressColor.Frame; frameProgress.Y = frameThum.Y + frameThum.Height / 2; frameProgress.Height = uiView.Frame.Height - frameProgress.Y; btnProgressColor.Frame = frameProgress; } } /// /// 滑动休眠时间 /// public int SleepTime = 0; uint progressColor = 0x99000099; /// /// 进度颜色 /// /// The color of the progress. public uint ProgressColor { get { return progressColor; } set { progressColor = value; if (!IsCanRefresh) { return; } int r = (byte)(progressColor / 256 / 256 % 256); int g = (byte)(progressColor / 256 % 256); int b = (byte)(progressColor % 256); int a = (byte)(progressColor / 256 / 256 / 256 % 256); btnProgressColor.BackgroundColor = UIKit.UIColor.FromRGBA(r, g, b, a); } } uint backgroundColor = 0xFFFFFFFF; /// /// 底部颜色 /// /// The color of the background. public new uint BackgroundColor { get { return backgroundColor; } set { backgroundColor = value; if (!IsCanRefresh) { return; } int r = (byte)(backgroundColor / 256 / 256 % 256); int g = (byte)(backgroundColor / 256 % 256); int b = (byte)(backgroundColor % 256); int a = (byte)(backgroundColor / 256 / 256 / 256 % 256); btnBackgroundColor.BackgroundColor = UIKit.UIColor.FromRGBA(r, g, b, a); } } uint thumbColor = 0xFFFFFFFF; /// /// 滑块颜色 /// /// The color of the background. public uint ThumbColor { get { return thumbColor; } set { thumbColor = value; if (!IsCanRefresh) { return; } int r = (byte)(thumbColor / 256 / 256 % 256); int g = (byte)(thumbColor / 256 % 256); int b = (byte)(thumbColor % 256); int a = (byte)(thumbColor / 256 / 256 / 256 % 256); btnThum.SetBackgroundImage(createImageWithColor(UIColor.FromRGBA(r, g, b, a)), UIControlState.Disabled); } } internal override bool TouchEvent(EventActions e, CGPoint point) { switch (e) { case EventActions.Down: dateTime = DateTime.Now; setButtonLoaction(point.Y); break; case EventActions.Move: setButtonLoaction(point.Y); break; case EventActions.Cancel: case EventActions.Up: dateTime = DateTime.MinValue; setButtonLoaction(point.Y); break; } return base.TouchEvent(e,point); } int beforValue = 0; void setButtonLoaction(nfloat y) { if (!IsCanScrolled) { return; } delayDateTime = DateTime.Now; if (y < 0) { y = 0; } if (validHeight < y) { y = validHeight; } var frameThum = btnThum.Frame; frameThum.Y = y; btnThum.Frame = frameThum; var frameProgress = btnProgressColor.Frame; frameProgress.Y = frameThum.Y + frameThum.Height / 2; frameProgress.Height = uiView.Frame.Height - frameProgress.Y; btnProgressColor.Frame = frameProgress; if (dateTime == DateTime.MinValue) { if (ProgressChanged != null && beforValue != Progress) { dateTime = DateTime.Now; delayDateTime = DateTime.Now; ProgressChanged(this, beforValue = Progress); } } else { //变化大于500毫秒的时候才通知 if (SleepTime < (DateTime.Now - dateTime).TotalMilliseconds) { dateTime = DateTime.Now; delayDateTime = DateTime.Now; if (ProgressChanged != null && beforValue != Progress) { ProgressChanged(this, beforValue = Progress); } } } } class MyVerticalSeekBar : UIView { [Weak] VerticalSeekBar view; public MyVerticalSeekBar(VerticalSeekBar view) { this.view = view; } public override UIView HitTest(CGPoint point, UIEvent uievent) { //如果点击是这个区域,不让其它视图执行事件 if (PointInside(point, uievent)) { return this; } return null; } nfloat startPointX; /// /// 点击开始 /// /// Touches. /// Evt. public override void TouchesBegan(NSSet touches, UIEvent evt) { parentScrolled(false); var cgpoint = (touches.AnyObject as UITouch).LocationInView(this); startPointX = cgpoint.X; view?.TouchEvent(EventActions.Down, (touches.AnyObject as UITouch).LocationInView(this)); } /// /// 移动 /// /// Touches. /// Evt. public override void TouchesMoved(NSSet touches, UIEvent evt) { var cgpoint = (touches.AnyObject as UITouch).LocationInView(this); if (20 < Math.Abs(cgpoint.X - startPointX)) { parentScrolled(true); } view?.TouchEvent(EventActions.Move, (touches.AnyObject as UITouch).LocationInView(this)); } /// /// 点击弹起 /// /// Touches. /// Evt. public override void TouchesEnded(NSSet touches, UIEvent evt) { parentScrolled(true); view?.TouchEvent(EventActions.Up, (touches.AnyObject as UITouch).LocationInView(this)); } public override void TouchesCancelled(NSSet touches, UIEvent evt) { parentScrolled(true); view?.TouchEvent(EventActions.Cancel, (touches.AnyObject as UITouch).LocationInView(this)); } /// /// 设置父视图是否可以滑动 /// /// If set to true b. void parentScrolled(bool b) { var tempParent = Superview; while (null != tempParent) { if (tempParent.GetType() == typeof(UIScrollView)) { (tempParent as UIScrollView).ScrollEnabled = b; } tempParent = tempParent.Superview; } } } } }