Add items in collection view when scrolled in Xamarin IOS - xamarin
I want to add new items to collection view when user scrolled the view.
I am able to add the items successful, but the scroll bar moved to top.
Please find my below code.
ViewControll Code:
public partial class ViewController : UIViewController
{
UIWindow window;
UICollectionViewController simpleCollectionViewController;
UICollectionViewFlowLayout flowLayout;
UIScrollView viewColle = new UIScrollView( new CGRect(0,100,UIScreen.MainScreen.Bounds.Width, 500));
int count = 2;
protected ViewController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
viewColle.BackgroundColor = UIColor.Green;
// Perform any additional setup after loading the view, typically from a nib.
// Flow Layout
flowLayout = new UICollectionViewFlowLayout () {
HeaderReferenceSize = new CGSize (0, 0),
SectionInset = new UIEdgeInsets (0, 0, 0, 0),
ScrollDirection = UICollectionViewScrollDirection.Vertical,
MinimumInteritemSpacing = 5, // minimum spacing between cells
MinimumLineSpacing = 5 // minimum spacing between rows if ScrollDirection is Vertical or between columns if Horizontal
};
simpleCollectionViewController = new MyCollectionViewController (flowLayout,count);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
UIButton btnClick = new UIButton()
{
Frame = new CoreGraphics.CGRect(0,0,UIScreen.MainScreen.Bounds.Width,50),
BackgroundColor = UIColor.Gray
};
btnClick.SetTitle("Click", UIControlState.Normal);
btnClick.TouchUpInside += (sender, e) => {
window = new UIWindow(UIScreen.MainScreen.Bounds);
count++;
//var nav = new UINavigationController(simpleCollectionViewController);
//window.RootViewController = nav;
//window.MakeKeyAndVisible();
if (count > 3)
count = count / 3;
if (count == 1)
{
simpleCollectionViewController = new ListViewController (flowLayout,count,2);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
else if (count == 2)
{
simpleCollectionViewController = new MyCollectionViewController (flowLayout,count);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
else if (count == 3)
{
simpleCollectionViewController = new DetailViewController (flowLayout,1);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
//viewColle.Frame = new CGRect(0, 100, UIScreen.MainScreen.Bounds.Width, 500);
nfloat height0 = 0;
CGRect contentRect0 = new CGRect();
foreach (UIView view in viewColle.Subviews) {
height0 += view.Bounds.Height;
}
contentRect0.Size = new CGSize(View.Bounds.Width, height0 );
viewColle.ContentSize = contentRect0.Size;
//viewColle.ContentSize = new CGSize(simpleCollectionViewController.View.Bounds.Width, 2000);
View.AddSubview(btnClick);
View.AddSubview(viewColle);
};
viewColle.AddSubview(simpleCollectionViewController.View);
//viewColle.Frame = new CGRect(0, 100, UIScreen.MainScreen.Bounds.Width, 500);
nfloat height1 = 0;
CGRect contentRect1 = new CGRect();
foreach (UIView view in viewColle.Subviews) {
height1 += view.Bounds.Height;
}
contentRect1.Size = new CGSize(View.Bounds.Width, height1 );
viewColle.ContentSize = contentRect1.Size;
CGRect contentRect = new CGRect();
foreach (UIView view in viewColle.Subviews) {
contentRect = view.Frame;
}
viewColle.ContentSize = contentRect.Size;
//viewColle.ContentSize = new CGSize(simpleCollectionViewController.View.Bounds.Width, 2000);
View.AddSubview(btnClick);
View.AddSubview(viewColle);
viewColle.Scrolled += (sender, e) => {
UIAlertView alert = new UIAlertView("Scrolled Alert", "Scroller "+ count.ToString(), null, "Cancel", null);
alert.Show();
if (count > 3)
count = count / 3;
if (count == 1)
{
simpleCollectionViewController = new ListViewController (flowLayout,count,10);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
else if (count == 2)
{
simpleCollectionViewController = new MyCollectionViewController (flowLayout,count);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
else if (count == 3)
{
simpleCollectionViewController = new DetailViewController (flowLayout,1);
simpleCollectionViewController.CollectionView.ContentInset = new UIEdgeInsets (0, 0, 0, 0);
viewColle.AddSubview(simpleCollectionViewController.View);
}
nfloat height = 0;
CGRect contentRect2 = new CGRect();
foreach (UIView view in viewColle.Subviews) {
height += view.Bounds.Height;
}
contentRect2.Size = new CGSize(View.Bounds.Width, height );
viewColle.ContentSize = contentRect2.Size;
//viewColle.Frame = new CGRect(0, 100, UIScreen.MainScreen.Bounds.Width, 500);
//viewColle.ContentSize = new CGSize(simpleCollectionViewController.View.Bounds.Width, 2000);
View.AddSubview(btnClick);
View.AddSubview(viewColle);
};
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
ListViewController Code:
public partial class ListViewController : UICollectionViewController
{
static NSString animalCellId = new NSString ("AnimalCell");
static NSString headerId = new NSString ("Header");
List<IProduct> products;
int devideValue = 0;
public ListViewController (UICollectionViewLayout layout,int divValue, int count) : base (layout)
{
devideValue = divValue;
products = new List<IProduct> ();
for (int i = 0; i < count; i++) {
Product pr = new Product();
pr.id = i;
pr.Price = i;
products.Add (pr);
}
}
[Export ("collectionView:layout:sizeForItemAtIndexPath:")]
public virtual CGSize GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
{
//For 2 items devide by 2
var width = (float)(UIScreen.MainScreen.Bounds.Width/devideValue);
return new CGSize (width - 10, 125);
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
CollectionView.RegisterClassForCell (typeof(ProductCell1), animalCellId);
CollectionView.RegisterClassForSupplementaryView (typeof(Header), UICollectionElementKindSection.Header, headerId);
UIMenuController.SharedMenuController.MenuItems = new UIMenuItem[] {
new UIMenuItem ("Add to Cart?", new Selector ("addCart"))
};
}
public override nint NumberOfSections (UICollectionView collectionView)
{
return 1;
}
public override nint GetItemsCount (UICollectionView collectionView, nint section)
{
return products.Count;
}
public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
var productCell = (ProductCell1)collectionView.DequeueReusableCell (animalCellId, indexPath);
var product = products [indexPath.Row];
productCell.Image = product.Image;
productCell.Price = product.Price;
productCell.Product = product.ProductName;
return productCell;
}
public override UICollectionReusableView GetViewForSupplementaryElement (UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath)
{
var headerView = (Header)collectionView.DequeueReusableSupplementaryView (elementKind, headerId, indexPath);
//headerView.Text = "Product View";
//headerView.btnText = "Click";
return headerView;
}
public override void ItemHighlighted (UICollectionView collectionView, NSIndexPath indexPath)
{
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.Red;
}
public override void ItemUnhighlighted (UICollectionView collectionView, NSIndexPath indexPath)
{
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.Green;
ProductCell1 productCell = (ProductCell1)collectionView.DequeueReusableCell (animalCellId, indexPath);
int itemIndex = (int)indexPath.Item;
Product prodt = new Product();
for (int i = 0; i < products.Count; i++)
{
if (indexPath.Item == i)
{
prodt = (Product)products[i];
break;
}
}
UIAlertView alert = new UIAlertView("Selected Item", prodt.id.ToString(), null, "Cancel", null);
alert.Show();
}
//public override void ItemSelected(UICollectionView collectionView, NSIndexPath indexPath)
//{
// //var cell = collectionView.CellForItem (indexPath);
// base.ItemSelected(collectionView, indexPath);
//}
public override bool ShouldHighlightItem (UICollectionView collectionView, NSIndexPath indexPath)
{
return true;
}
// for edit menu
public override bool ShouldShowMenu (UICollectionView collectionView, NSIndexPath indexPath)
{
return true;
}
public override bool CanPerformAction (UICollectionView collectionView, Selector action, NSIndexPath indexPath, NSObject sender)
{
// Selector should be the same as what's in the AddCart UIMenuItem
if (action == new Selector ("addCart"))
return true;
else
return false;
}
public override void PerformAction (UICollectionView collectionView, Selector action, NSIndexPath indexPath, NSObject sender)
{
System.Diagnostics.Debug.WriteLine ("code to perform action");
}
// CanBecomeFirstResponder and CanPerform are needed for a AddCart menu item to appear
public override bool CanBecomeFirstResponder {
get {
return true;
}
}
}
public class ProductCell1 : UICollectionViewCell
{
UIImageView imageView;
UILabel productName;
UILabel manufacturer;
UIView cellViewContainer;
UILabel price;
[Export ("initWithFrame:")]
public ProductCell1 (CGRect frame) : base (frame)
{
BackgroundView = new UIView{ BackgroundColor = UIColor.DarkGray };
SelectedBackgroundView = new UIView{ BackgroundColor = UIColor.Green };
ContentView.Layer.BorderColor = UIColor.LightGray.CGColor;
ContentView.Layer.BorderWidth = 2.0f;
ContentView.BackgroundColor = UIColor.Gray;
cellViewContainer = new UIView ();
cellViewContainer.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
imageView = new UIImageView (UIImage.FromBundle ("placeholder.png"));
productName = new UILabel {
Text = "Name",
TextColor = UIColor.Black,
BackgroundColor = UIColor.White,
TextAlignment = UITextAlignment.Left
};
manufacturer = new UILabel {
Text = "Price",
TextColor = UIColor.Black,
BackgroundColor = UIColor.Red,
TextAlignment = UITextAlignment.Left
};
price = new UILabel {
Text = "Price",
TextColor = UIColor.Black,
BackgroundColor = UIColor.Red,
TextAlignment = UITextAlignment.Left
};
//productName.Frame = new CGRect (5, 5, labelWidth, labelHeight);
//price.Frame = new CGRect (5, labelHeight, labelWidth, labelHeight);
//imageView.Frame = new CGRect (labelWidth, 0, labelWidth, ContentView.Bounds.Height - 2);
imageView.Frame = new CGRect (3,3, ContentView.Bounds.Width/2, ContentView.Bounds.Height-3);
productName.Frame = new CGRect (ContentView.Bounds.Width/2 + 5, 3, ContentView.Bounds.Width/2 - 5, 20);
manufacturer.Frame = new CGRect (ContentView.Bounds.Width/2 + 5, 23, ContentView.Bounds.Width/2 - 5, 20);
price.Frame = new CGRect (ContentView.Bounds.Width/2 + 5, 43, ContentView.Bounds.Width/2 - 5, 20);
ContentView.AddSubviews (new UIView[] { imageView, productName, manufacturer, price });
}
public void UpdateCell ()
{
productName.Frame = new CGRect (10, 10, ContentView.Bounds.Width / 2, ContentView.Bounds.Height / 3);
price.Frame = new CGRect (20, 20, ContentView.Bounds.Width / 2, ContentView.Bounds.Height / 3);
}
public UIImage Image {
set {
imageView.Image = value;
}
}
public string Product {
set {
productName.Text = value;
}
}
public double Price {
set {
price.Text = value.ToString ("$0.00");
}
}
[Export ("addCart")]
void AddCart ()
{
// Put all your addCart menu behavior code here
Console.WriteLine ("addCart in the cell");
}
public override bool CanPerform (Selector action, NSObject withSender)
{
if (action == new Selector ("addCart"))
return true;
else
return false;
}
}
after adding the items to view the scroll bar moves to top. Please can any one suggest me to solve this.
Related
How draw a rectangle hole on UIBlurEffect and move it on x axis (UIKit)
I'm trying to create blur effect on a view and than add a shape which will show image on this blurred layer (custom video editing functionality) Currently I'm able to do it only dragging mask view from the right edge: but when I try to do it from the left edge, I get such a effect: func configureBlurView() { let viewHeight: CGFloat = 60 let padding: CGFloat = 10 blurView = UIView() blurView.layer.cornerRadius = 10 blurView.clipsToBounds = true blurView.isHidden = true blurView.translatesAutoresizingMaskIntoConstraints = false addSubview(blurView) addConstraints([ blurView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding), blurView.bottomAnchor.constraint(equalTo: stackView.topAnchor, constant: -padding), blurView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding), blurView.heightAnchor.constraint(equalToConstant: viewHeight) ]) addBlurEffect(for: blurView) } private func addBlurEffect(for view: UIView) { let blurEffect = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) blurEffect.alpha = 0.5 blurEffect.translatesAutoresizingMaskIntoConstraints = false view.addSubview(blurEffect) addConstraints([ blurEffect.topAnchor.constraint(equalTo: view.topAnchor), blurEffect.leadingAnchor.constraint(equalTo: view.leadingAnchor), blurEffect.bottomAnchor.constraint(equalTo: view.bottomAnchor), blurEffect.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) } private func makeClearHole(rect: CGRect) { let maskLayer = CAShapeLayer() maskLayer.fillColor = UIColor.black.cgColor let pathToOverlay = CGMutablePath() pathToOverlay.addRect(blurView.bounds) pathToOverlay.addRect(rect) maskLayer.path = pathToOverlay maskLayer.fillRule = .evenOdd maskLayer.cornerRadius = 10 blurView.layer.mask = maskLayer } I'm using touchesMoved method to change orange view dimensions: override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard trimmerView.isHidden == false else { return } if let touch = touches.first{ let currentTouchPoint = touch.location(in: self) let previousTouchPoint = touch.previousLocation(in: self) let deltaX = currentTouchPoint.x - previousTouchPoint.x if trimmerView.bounds.width >= 70 { if touchStartEdge.middle { if trimmerViewLeadingConstraint.constant < 10 { trimmerViewLeadingConstraint.constant = 10 } else if trimmerViewTrailingConstraint.constant > -10 { trimmerViewTrailingConstraint.constant = -10 } else { trimmerViewLeadingConstraint.constant += deltaX trimmerViewTrailingConstraint.constant += deltaX } } if touchStartEdge.leftEdge { if trimmerViewLeadingConstraint.constant >= 10.0 { trimmerViewLeadingConstraint.constant += deltaX } else if trimmerViewLeadingConstraint.constant < 10.0 { trimmerViewLeadingConstraint.constant = 10 } } if touchStartEdge.rightEdge { if trimmerViewTrailingConstraint.constant <= -10 { trimmerViewTrailingConstraint.constant += deltaX } else if trimmerViewTrailingConstraint.constant > -10 { trimmerViewTrailingConstraint.constant = -10.0 } } } updateProgressBarConstraints() makeClearHole(rect: CGRect(x: 0, y: 0, width: trimmerView.frame.width, height: trimmerView.frame.height)) UIView.animate(withDuration: 0.10, delay: 0, options: .curveEaseIn) { [weak self] in self?.layoutIfNeeded() } } } What I'd like to achieve is to remove blur effect only in bounds of orange view. Any ideas ?? :) Thanks for help!!
Couple ways to do this - here's one... Add a mask to the blur effect view. As the user drags the "trimmer" update the mask. Here's a quick example... We'll: create a stack view with 10 images overlay that with a masked blur effective view add a "draggable trimmer view" when we drag the trimmer, we update the mask Example View Controller class TrimmerVC: UIViewController { var blurView: MaskedBlurView! let trimmerView = DragView() let stackView = UIStackView() override func viewDidLoad() { super.viewDidLoad() // respect safe area when we setup constraints let g = view.safeAreaLayoutGuide stackView.distribution = .fillEqually stackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0), stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0), stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0), stackView.heightAnchor.constraint(equalToConstant: 80.0), ]) // let's add 10 imageviews to the stack view for i in 1...10 { if let img = UIImage(systemName: "\(i).circle.fill") { let imgView = UIImageView(image: img) imgView.backgroundColor = UIColor(white: 0.95, alpha: 1.0) stackView.addArrangedSubview(imgView) } } let blurEffect = UIBlurEffect(style: .dark) blurView = MaskedBlurView(effect: blurEffect) blurView.alpha = 0.5 blurView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(blurView) NSLayoutConstraint.activate([ blurView.topAnchor.constraint(equalTo: stackView.topAnchor, constant: 0.0), blurView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 0.0), blurView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 0.0), blurView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 0.0), ]) trimmerView.backgroundColor = .systemOrange view.addSubview(trimmerView) trimmerView.didDrag = { [weak self] newX in guard let self = self else { return } self.blurView.clearX = newX - self.stackView.frame.origin.x } } // we'll use this to update the framing when the stack view width changes // such as on device rotation var curStackW: CGFloat = -1 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() if curStackW != stackView.frame.width { curStackW = stackView.frame.width var r = stackView.frame r.origin.y += r.size.height + 20.0 r.size.width = 160 r.size.height = 40 trimmerView.frame = r blurView.clearWidth = trimmerView.frame.width blurView.clearX = 0 } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // toggle the trimmer view between // below the stack view and // overlaid on the stack view if trimmerView.frame.origin.y > stackView.frame.origin.y { let r = stackView.frame trimmerView.frame.origin.y = r.origin.y - 6.0 trimmerView.frame.size.height = r.height + 12.0 } else { let r = stackView.frame trimmerView.frame.origin.y = r.origin.y + r.height + 12.0 trimmerView.frame.size.height = 60.0 } } } Example Draggable "Trimmer" View class DragView: UIView { var didDrag: ((CGFloat) -> ())? let maskLayer = CAShapeLayer() override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) commonInit() } func commonInit() { maskLayer.fillColor = UIColor.red.cgColor layer.mask = maskLayer } override func layoutSubviews() { super.layoutSubviews() let pathToOverlay = CGMutablePath() pathToOverlay.addRect(bounds) pathToOverlay.addRect(bounds.insetBy(dx: 20.0, dy: 8.0)) maskLayer.path = pathToOverlay maskLayer.fillRule = .evenOdd maskLayer.cornerRadius = 10 } var touchStartX: CGFloat = 0 var frameStartX: CGFloat = 0 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } touchStartX = touch.location(in: self.superview!).x frameStartX = self.frame.origin.x } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } let loc = touch.location(in: self.superview!) self.frame.origin.x = frameStartX + (loc.x - touchStartX) didDrag?(self.frame.origin.x) } } Example Masked Blur View class MaskedBlurView: UIVisualEffectView { public var clearWidth: CGFloat = 100 { didSet { updateMask() } } public var clearX: CGFloat = 0 { didSet { updateMask() } } private let maskLayer = CAShapeLayer() override init(effect: UIVisualEffect?) { super.init(effect: effect) commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) commonInit() } func commonInit() { maskLayer.fillColor = UIColor.red.cgColor layer.mask = maskLayer } func updateMask() { let leftR = CGRect(x: 0, y: 0, width: clearX, height: bounds.height) let rightR = CGRect(x: clearX + clearWidth, y: 0, width: bounds.width, height: bounds.height) let bez = UIBezierPath(rect: leftR) bez.append(UIBezierPath(rect: rightR)) maskLayer.path = bez.cgPath } override func layoutSubviews() { super.layoutSubviews() maskLayer.frame = bounds } } When running (in landscape orientation) it will start like this: I placed the "trimmer" view below the stack view to make it a little more clear what's happening. As we drag the trimmer view, the blur view's mask will be updated: Tapping anywhere in an empty part of the screen will toggle the trimmer view between "under the stack view" and "overlaid on the stack view": This was just put together quickly -- you should have no trouble restructuring the code to wrap everything into a single custom view (or however it would work best for your needs).
Is there an property like android:actionBarSize in iOS?
I'm developing in Xamarin and I don't know how change the height of navigation bar. For android is easier because you've got a clear property "ActionBarSize" I've tried a lot of things. Create a comun NavigationPage with HeightRequest property does not work Thanks a lot
In iOS we could set a custom TitlView by using custom renderer . using Foundation; using UIKit; using Xamarin.Forms.Platform.iOS; using Xamarin.Forms; using xxx.iOS; using CoreGraphics; using xxx; using ObjCRuntime; [assembly: ExportRenderer(typeof(ContentPage), typeof(MyPageRenderer))] namespace xxx.iOS { public class MyPageRenderer: PageRenderer { public override void ViewWillAppear(bool animated) { base.ViewWillAppear(animated); var page = Element as ContentPage; NavigationController.NavigationBar.Hidden = true; double height = IsiphoneX(); UIView backView = new UIView() { BackgroundColor = UIColor.White, Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height), }; UIButton backBtn = new UIButton() { Frame = new CGRect(20, height-44, 40, 44), Font = UIFont.SystemFontOfSize(18), } ; backBtn.SetTitle("Back", UIControlState.Normal); backBtn.SetTitleColor(UIColor.Blue, UIControlState.Normal); backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside); UILabel titleLabel = new UILabel() { Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height), Font = UIFont.SystemFontOfSize(20), Text = page.Title, TextColor = UIColor.Black, Lines = 0, }; UILabel line = new UILabel() { Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5), BackgroundColor = UIColor.Black, }; backView.AddSubview(backBtn); backView.AddSubview(titleLabel); backView.AddSubview(line); View.AddSubview(backView); } double IsiphoneX() { double height = 44; //set height as you want here !!! if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)) { if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0) { height = 64; //set height as you want here !!! } } return height; } [Export("GoBack")] void GoBack() { NavigationController.PopViewController(true); } public override void ViewWillDisappear(bool animated) { base.ViewWillDisappear(animated); NavigationController.NavigationBar.Hidden = false; } } }
How to make the clicks from one UIViewController pass into the parent UIViewController through the hole
I have UIViewController (OverlayViewController), which overlay another UIViewController(RootViewController). In OverlayViewController I add UIView for all frame size: var overlayView = new UIView(OverlayViewController.View.Frame); overlayView.Alpha = 0.5f; overlayView.BackgroundColor = UIColor.Blue; overlayView.UserInteractionEnabled = false; View.AddSubview(overlayView); Then I make a hole: var path = new CGPath(); var radius = 50.0f; var xOffset = 100; var yOffset = 300; path.AddArc(overlayView.Frame.Width - radius / 2 - xOffset, yOffset, radius, 0.0f, (nfloat) (2 * 3.14), false); var cgRect = new CGRect(0, 0, overlayView.Frame.Width, overlayView.Frame.Height); path.AddRect(cgRect); maskLayer.BackgroundColor = UIColor.Black.CGColor; maskLayer.Path = path; maskLayer.FillRule = CAShapeLayer.FillRuleEvenOdd; overlayView.Layer.Mask = maskLayer; overlayView.ClipsToBounds = true; When I set overlayView.UserInteractionEnabled = false; I could touch through OverlayViewController and all clicks worked. How I can properly use UITapGestureRecognizer so that clicks by items on the RootViewController work only inside the circle? And all the other clicks were blocked. I tried set overlayView.UserInteractionEnabled = true;, but it doesn't help me: tap.ShouldReceiveTouch += (recognizer, touch) => { return !path.ContainsPoint(touch.LocationInView(overlayView), true); }; View.AddGestureRecognizer(tap); I use Xamarin, but I can understand the decision on Swift too.
I found the solution... I make custom UIView which can set CGPath. public class OverlayView : UIView { public OverlayView(CGRect frame): base(frame) {} private CGPath _path; public override bool PointInside(CGPoint point, UIEvent uievent) { return _path.ContainsPoint(point, true); } public void SetPoint(CGPath path) { _path = path; } } And set overlayView.SetPoint(path);. In OverlayView I override PointInside and check my touch points. Also, I set overlayView.UserInteractionEnabled = true;.
How to make only forward and backword textbox focus in xamarin IOS with UItextfield?
I want to enter 6 digit verification code only in forward direction means left to right and for deleting right to left on UITextfield. Use can not focus on in between text field ..if he wants to delete or change any text box value then he has to delete from the right and reach on the most left side text box. you can see below image
Firstly, we can create a view and add a textView in it for editing like: UIView containView = new UIView(new CGRect(0, 200, 300, 50)); View.AddSubview(containView); UITextView textView = new UITextView(); textView.TintColor = UIColor.Clear; textView.BackgroundColor = UIColor.Clear; textView.TextColor = UIColor.Clear; textView.Frame = containView.Bounds; textView.Delegate = new MyTextViewDelegate(this); textView.KeyboardType = UIKeyboardType.NumberPad; containView.AddSubview(textView); Then we can draw six label in it for displaying the number, and six pointer line, also with bottom line like: for (int i = 0; i < 6; i++) { UILabel label = new UILabel(); label.Frame = new CGRect(i * 50, 0, 50, 50); label.TextAlignment = UITextAlignment.Center; label.TextColor = UIColor.Black; containView.AddSubview(label); labelArr.Add(label); UIView pointerLine = new UIView(new CGRect(i * 50 + 25, 12, 1, 26)); pointerLine.BackgroundColor = UIColor.Blue; containView.AddSubview(pointerLine); pointerLine.Layer.AddAnimation(opacityAnimation(), "kOpacityAnimation"); pointlineArr.Add(pointerLine); if (i > 0) pointerLine.Hidden = true; UIView line = new UIView(new CGRect(i * 50 + 5, 48, 40, 2)); line.BackgroundColor = UIColor.Gray; containView.AddSubview(line); lineArr.Add(line); } To make the pointerLine flashing when we are editing, we can add an animation to the pointerLine like: CABasicAnimation opacityAnimation() { CABasicAnimation opacityAnimation = CABasicAnimation.FromKeyPath("opacity"); opacityAnimation.From = NSNumber.FromNFloat(1); opacityAnimation.To = NSNumber.FromNFloat(0); opacityAnimation.Duration = 0.9; opacityAnimation.RepeatCount = float.MaxValue; opacityAnimation.RemovedOnCompletion = true; return opacityAnimation; } At last we can do some configuration in the textView's delegate to get your effect when we try to add or delete a number. This is my delegate file for you to refer to: public class MyTextViewDelegate : UITextViewDelegate { ViewController superViewController; public MyTextViewDelegate(ViewController viewController) { superViewController = viewController; } public override void Changed(UITextView textView) { string verStr = textView.Text.Replace(" ", ""); for (int i = 0; i < superViewController.labelArr.Count; i++) { UILabel label = superViewController.labelArr[i]; UIView pointerLabel = superViewController.pointlineArr[i]; if (i < verStr.Length) { changeViewLayer(i, true); label.Text = verStr.Substring(i, 1); } else { changeViewLayer(i, false); label.Text = ""; } pointerLabel.Hidden = true; } if (verStr.Length >= 6) { textView.Text = verStr.Substring(0, 6); endEdit(); return; } else { superViewController.pointlineArr[verStr.Length].Hidden = false; } } void endEdit() { superViewController.View.EndEditing(true); } void changeViewLayer(int index, bool isHidden) { UIView line = superViewController.lineArr[index]; if (isHidden) { line.BackgroundColor = UIColor.Red; } else { line.BackgroundColor = UIColor.Gray; } } }
How can I set the size of a UITextView to 100?
I am using this code to create a UITextView that's added to a footer. public override UIView GetViewForFooter(UITableView tableView, nint section) { var txtView = new UITextView { Editable = false, Text = "Select or deselect cards from the list above and they will added or removed from the card deck,", TextAlignment = UITextAlignment.Justified, TextContainerInset = new UIEdgeInsets(top: 10, left: 15, bottom: 5, right: 5), BackgroundColor = Color.Transparent.ToUIColor() }; txtView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap; return txtView; } Can anyone tell me how I can make this UITextView had a height of 100?
public override UIView GetViewForFooter(UITableView tableView, nint section) { var txtView = new UITextView(new Rectangle(0,0,0,100)) { .......... }; ........ } Try this hope it helps.
Override the method GetHeightForFooter public override nfloat GetHeightForFooter(UITableView tableView, nint section) { return 100; } set frame on UITextView public override UIView GetViewForFooter(UITableView tableView, nint section) { var txtView = new UITextView { Frame = new CGRect(0,0, tableView.Frame.Width,100), Editable = false, Text = "Select or deselect cards from the list above and they will added or removed from the card deck,", TextAlignment = UITextAlignment.Justified, TextContainerInset = new UIEdgeInsets(top: 10, left: 15, bottom: 5, right: 5), BackgroundColor = Color.Transparent.ToUIColor() }; txtView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap; return txtView; }