Custom UIView not working in Xamarin - uiview

I am trying to subclass UIView using Xamarin but don't seem to be getting the results I expect. To keep things simple, I have the following class:
using System;
using CoreGraphics;
using Foundation;
using UIKit;
namespace ExerciseTracker.iOS.Views
{
[Register("CustomView")]
public class CustomView : UIView
{
public override void Draw(CGRect rect)
{
base.Draw(rect);
}
}
}
A breakpoint is set on the base.Draw(rect); line. A view exists in my Storyboard layout with its class set to CustomView.
However, when the app is run and the page is shown, the breakpoint is never hit, and the breakpoint it displayed as though it will never be hit.
This is using Visual Studio for Mac v7.1.5. Is there anything I'm missing here? It seems like it should be quite simple, but I've been stuck for a few hours on this.

You need to add a construct with IntPtr parameter in CustomView class, like this:
public CustomView(IntPtr p): base(p)
{
//Your initialization code.
}
Then this class can be used in storyboard directly.
More details you can refer to this Xamarin official documentation:
Walkthrough - Using Custom Controls with the Xamarin Designer for iOS.

Related

Maui Handler, Confused at what to put inside of CreatePlatformView iOS

I have a custom view which previously was a Grid but I have changed its class inheritance to a View as this to me seems like the correct thing to do based on what I have read online.
This custom view has content inside of it. (A grid Which has content inside of itself)
This custom View has a handler in the native code.
Then each project has its own version of the handler, where I can handle the mapping methods.
I am adding the content from my custom view to the platform view using a ContentMapper (Inside the native iOS handler)
public static void MapContent(MyHandler handler, MyView view)
{
if (view.Content == null)
return;
handler.PlatformView.AddSubview(view.Content.ToPlatform(handler.MauiContext));
}
And inside of CreatePlatformView() (Native iOS project) I currently have.
UIView uIView = new UIView();
uIView.BackgroundColor = UIColor.Yellow;
return uIView;
But I can't see any of my content, I can however see the yellow background takes up the whole page.
I Have tried doing this inside of the CreatePlatformView()
VirtualView.ToPlatform(VirtualView.Handler.MauiContext) But one it doesn't work and two I don't think that should work anyway.
I could be doing it all wrong I am unsure. If needed I can create a demo project and upload it to GitHub.

Adding images with PaintCode into Xcode 7 using Swift 2.0

I am trying to move a swift file that I exported from PaintCode 2 into my project. I did the following.
Exported the project via PaintCode
Moved the file into Xcode
On my storyboard I put a UIView
Clicked on the newly created UIView and selected the class that I imported from PaintCode.
Now I am looking a white box:
Now the file I got from PaintCode was of type NSObject which I knew couldn't be right so I changed it to UImage. Still getting the same result.
---------UPDATE-----------
I created a new Cococa Class of type UIView, and did the following:
#IBDesignable
class CareerButtonClass: UIView {
//CareerButton.drawCanvas2()
func drawCareerButton() {
CareerButton.drawCanvas2()
}
}
Then I named the custom class on IUView in the storyboard CareerButtonClass.
Here are what my files look like:
Still getting the same result.
For those who run by this post I finally found a good example here:
PaintCode Tutorial for Developers (Swift 2.0): Getting Started
That's because PaintCode exports a class with a collection of methods that you can use to draw the content.
Depending on the methods you choose, it can either generate a UIImage for you or you can call the code to draw in the current context.
It's up to you to implement where to use those methods.
The class you got from PaintCode is NSObject and it’s right. StyleKit is a collection of all graphics you use in your app.
To render the button, you need to override drawRect method in your UIView. And call the method to draw the Career Button.
#IBDesignable
class CareerButtonClass: UIView {
override func drawRect(rect: CGRect) {
StyleKit.drawCareerButton()
}
}
See PaintCode FAQ #29.

No ItemSelected call in my UICollectionView?

So I'm trying out Xamarin Forms, and I made a control that has a renderer that outputs a UICollectionView. The collection view in question was ported from an Objective C version. In the Objective C version, I implemented collectionView:didSelectItemAtIndexPath: and when I clicked on the item that method was called. But in the Xamarin version, this does not seem to be the case and the ItemSelected method is not called. I've tried using both the Delegate and WeakDelegate versions to no avail. I made sure AllowsSelection is true.
I tried adding a UIButton to the cell, and was able to get a log entry from its TouchUpInside handler, so I don't think it's a matter of another view on top stealing the touches. Pans and such work. And in Simulator I had it highlight the drawn layers and didn't notice anything fishy.
Anyone have any ideas of stuff to try? Thanks.
I don't know if this can help you, but i get the same problem using the GridView control of the Xamarin.Forms.Labs.
I see that in delegate, the method "ItemSelected" is not called, but is call the "ItemHighlighted" method. So I used this to make the GridView selectitem works.
I hope this can be helpfull. :)
Double check that you have assigned the UICollectionViewSource object to ColelctionView.Source and NOT ColelctionView.DataSource by mistake
I did eventually fix this. What was happening is that Xamarin.Forms adds a gesture recognizer to the root of the page which cancels touches in the page. This works well in general, but does not work well in the case of UICollectionViews where it interferes with the UICollectionView calling ItemSelected.
What I ended up doing was to create this custom renderer:
public class IosTapFixPageRenderer : PageRenderer {
public override void ViewDidLoad()
{
base.ViewDidLoad();
foreach (var g in View.GestureRecognizers) {
g.CancelsTouchesInView = false;
}
}
}
Then I assigned this as the renderer for problem pages containing UICollectionViews using the usual attribute method:
[assembly: ExportRenderer(typeof(CalendarPage), typeof(IosTapFixPageRenderer))]

Global hook for showing UIViews

I have an iOS app I'm working on using Xamarin and MVVMCross, but I am also using a third-party native library which includes some views of it's own (loaded from .xib files with the implementation in the library). What I need to do is set some properties on those native views and I'm trying to see if there's a way to do it that doesn't involve jumping into xcode and trying to recompile that whole thing (because I can't get that working at the moment).
So my question is, is there a way to intercept, application-wide, all attempts to load a view so that I can examine the view and if it's one of those from the third-party library, set some properties on it before it's displayed?
MvvmCross has a MvxTouchViewPresenter which has a ChangePresentation property, but it seems to only apply to MvxViewController loaded by MvvmCross itself.
You can very easily intercept all attempts to access a viewmodel by overriding the Show() method on your MvxTouchPresenter. For example:
public override void Show(MvxViewModelRequest request)
{
IMvxTouchView view = this.CreateViewControllerFor(request);
UIViewController viewController = (UIViewController) view;
this.Show(view);
}
You can then examine all Views in the UIView heirarchy by using something similar to the Objective-C code in this post. You just need to walk through all the UIViews in the viewController property and identify your view (perhaps by "smelling it" with respondsToSelector; I can't figure out exactly how you'd use isKindOfClass if Xamarin doesn't know it).
I hope I understood your question. Let me know if there's anything else missing.

MvxViewModelRequest is null in ViewDidLoad

I'm using MvvmCross 3.0.12 in an iPad project. Currently, I'm getting a NPE in MvxViewControllerExtensionMethods.LoadViewModel, because touchView.Request is null. This is only happening in a view controller that is inheriting from MvxTableViewController; view controllers inheriting from MvxViewController load and display just fine.
I've set breakpoint in MvxTouchViewsContainer.CreateView -> MyTableViewController.Ctor -> MvxBaseTouchViewPresenter.Show -> MyTableViewController.LoadView; which have all referenced the same instance of the class. Then when I hit a breakpoint in ViewDidLoad, its a new instance and all of the properties including Request are null.
Is this a bug with Xamarin.iOS or am I doing something wrong?
This sometimes happens for view controllers like table, tab bar and collection.
It's caused, I think, by something in the Objective C base class init referencing the View - and thus triggering ViewDidLoad before the C# construction is fully complete. This is a bit like what can happen in 'pure' c# if a base class constructor references a virtual method.
To check this is occurring for your app, put 2 breakpoints in your app - one in the ViewController constructor and one in ViewDidLoad - if ViewDidLoad is fired first, then you know this is the case.
The only way around this I've found is to code around this by triggering a second ViewDidLoad call in the constructor.
public FirstView()
{
// need this additional call to ViewDidLoad because UIkit creates the view before the C# hierarchy has been constructed
ViewDidLoad();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
if (ViewModel == null)
return;
// ...
If it helps:
I believe I've talked about this in at least one N+1 - maybe N=25 - see https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-25-Tabbed/Tabbed.Touch/Views/FirstView.cs and http://mvvmcross.wordpress.com
The same type of thing happens in pure objective C code - eg see initialize UITableViewController with [super initWithStyle:UITableViewStyleGrouped]

Resources