Custom renders of nuGet Package conflict in Xamarin.forms - xamarin

I'm making app with using Xamarin.forms. (PCL)
I just noticed serious problem of using custom renderer.
I came from this thread.
https://forums.xamarin.com/discussion/54317/new-xamarin-forms-guide-custom-renderers/p2
This thread says, and I experienced that Only ONE renderer class works at the same time.
It means that if two different package use same renderer, one of them will not work. (It follows class hierarchy. so subclassed class will work and other stop working)
Package just added might break original package or mine, and real problem is that developer might not notice at that time.
Why is that how it works?
Or, am I not correct or did mistake?
example
If you already made your custom renderer for ContentPage and installed package which has custom renderer for ContentPage or Page. In my case, KeyboardOverlap.Forms.Plugin does. And Both Renderer class overrided OnApearing(). When you run your app. Only one renderer's OnApearing will be fired.
Of course I can hand merge that. But what if both of them are nuGet Package and can not modify them. (Of course I can use Github's but that cause another problem)

Each custom renderer should have a unique name. The only way you'll get collisions is if your renderer is overriding the base class... NEVER DO THAT, but instead you should inherit from the default and make sure to call base when you override.
If a nuget package is broken because they're overriding the default, you have to tell them to fix it.
In the code you're referring to, the author is overriding Page instead of making his own KeyboardOverlapPage
This line is causing you pain!
Instead it should be
[assembly: ExportRenderer (typeof(KeyboardOverlapPage), typeof(KeyboardOverlapRenderer))]
And then have a class in the PCL
public class KeyboardOverlapPage : Xamarin.Forms.Page {}
In other words, the author has a poorly implemented package and should fix it. Once fixed, you can use a wherever you want that functionality in place of a page.
If there is no custom renderer on a specific platform, it will automagically fall back to the default behaviour.

Related

NativeScript: use custom objective-c imported class into Xcode project in NativeScript

basically I have some Objective-c class already existing and I want to use them in my NativeScript projet. Currently I have added those files to the Xcode project target and I want to be able to call my objective-c code from nativeScript js. I've read the doc but I don't understand it. It seems so complicated. basically currently all I want to do is be able to present my custom view controller by calling probably something along
const vc = MyCustomViewController.alloc.initWithNibName("xib file")
page.frame.ios.controller.present(vc,true, nil)
Am I obligated to create a plugin for that? Am I obligated to use my objective-c class to build a framework in Xcode and then import the framework?
So I found out.
Actually what you need to do is first to compile your native iOS code into a framework. As per the documentation all your classes must inherit NSObject and all your function must be marked with #objc to be exposed to the objective-c Nativescript side if you write in swift. You will notice as well that in a framework your bundle is not the main bundle. In this example you can see how you can retrieve the bundle from the framework and load a xib from it.
Then you need to add your framework file to a Nativescript plugin. For that, you want to add the framework to the plugin's iOS folder yourPlugin/platform/iOS/yourFramework.framework.
then, you need to add your plugin to your app. You can add your local plugin by using the next command line. Notice the path end with the /src folder.
tns plugin add /path/to/yourplugin/src
Now, you can then call your native functions and classes without even importing them. Of course this works only on iOS. If you run your app on android, calling those methods will crash.
To show this viewController on your Nativescript side you will need to call the following code. By the way You can find documentation elsewhere to get a reference to the current page or frame object.
const controller = page.frame.ios.controller
const vc = IOMediaViewController.create()
vc.modalPresentationStyle = UIModalPresentationFullScreen
controller.presentViewControllerAnimatedCompletion(vc,true,null)

Xcode not allowing any classes is my custom framework in Interface Builder as custom classes

I have a custom class TULabel which derives from regular UILabel in my custom framework (which is another target inside the same project with my app). I have used my custom class in Interface Builder for months with no issues: I've selected a label, went to Custom Class, started typing my custom class name and it even completed itself.
I've been working on this project for long time and today I've realized I can't type TULabel into the custom class box anymore. I can type almost anything, even classes that don't exist. But when I try to type TULabel (or any other custom class from my framework) it just reverts to the previous value:
The only way for me to use my custom classes is to open up the Nib/Storyboard as source code, and type my custom class there which is, obviously, not acceptable. Weird enough, when I run my app it builds and runs correctly, with the custom label there (and I'm sure that it's the actual custom class instance and not runtime ignoring my custom class and reverting to label as it has custom drawing behavior which is displayed)
I have no idea when and where it broke since I've been working on the project for so long time and haven't tried to add a custom class for weeks.
I've tried opening and closing Xcode, cleaning my project and derived data folder, rebuilding the project but no avail. It's still the same.
Why is Interface Builder explicitly disallowing my class and how can I make Interface Builder accept my custom class name again?
I am on Xcode 9.2.

How to customize Xamarin.Forms app?

How can I customize the appearence of xamarin.forms components?
I want each button to have the same image, for instance. Or for all systems to share the same login screen with the same background image.
I know I can do that by adding one specific screen to each platform project. But I want to be able to customize the component itself. Example: All buttons will have the same background image no matter which platform is running.
I've read these:
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/styles/
http://code.tutsplus.com/tutorials/getting-started-with-xamarinforms-customizing-user-interface--cms-22144
The most promising one seems to be the last one. Is a custom renderer the only way to accomplish this? Can't I just add an image at the shared project and it automagicaly works for all platforms?
Thanks.
It's not absolutely clear, what exactly you want to reach... but I try to answer you.
If you use a shared project (based on template "Blank App (Xamarin.Forms shared)", you can use the same page / page-definition in all of your platforms.
You can add - e.g. a login-form in the shared-folder and then call it from code (e.g. from another page in the shared folder).
If you want to create your own controls, you can create "user-controls" and use it everywhere you want (what I recommend to every user).
You do this, by create a own class (e.g. with an Entry and a Label), implement the events and then instantiate it where you want to use it. E.G.
var OeFirma = new EntryErfassung(cDefaultText: "Firma", iMaximalLaenge: 45);
where OeFirma is the name of the object-instance on the page (to access it), EntryErfassung is my own class (that contains a description-label, an Entry an error-label and more) and cDefaultText is a parameter, that overtakes and set the default-text to the Entry and iMaximalaenge is a further parameter that is overtaken whereby my class then take care, that not more then 45 Characters are accepted for this Entry).
I have e.g. created a class with a description-label, a delete-button, an Entry and a error-label ad use it on all data-entry-forms.
If you want to change the look-and-feel of a specific control for a specific platform, you can create a "custom-render" (I have done this e.g. to change the font-size to the edit specific for iOS, as the font-sinze cannot be set in the XF-Entry control).
Hope this answers your question...
To do this, you can just specific a style in the App class, (you will need to change the app class to be made up of 2 partials: App.xaml & App.xaml.cs, and then create a ResourceDictionary to hold your customisations.
<Style TargetType="Button">
<Setter Property="Image" Value="MyImage.png"/>
</Style>
Hope that helps.
Cheers,
Tristan

Unknown class in Interface Builder file. Xcode 6 and Swift

I started a vanilla master detail project with swift. If I add a new view controller and set the custom class, then the modules list is empty and it is not possible to choose a module. The error message "Unknown class in Interface Builder file." appears in the console if I run the code.
How can I setup the storyboard to know the custom class and module?
How it should be. The two classes from the template are just fine.
and how it is
I have to add customModule="Target_Name" customModuleProvider="target" to the interface builder source code. That is really annoying!
Update:
If I move the whole project directory to another, e.g. to the desktop it works. Looks like my directory with the name "Repository" is broken. Don't know why :(
I used to encounter the same issue, I finally found that the StoryBoard's Target Membership has been set incorrectly
.
I was getting the same problem but I discovered that I had inadvertently assigned a non-existing custom class to the view object managed by my view controller. So in the storyboard document view, I selected the badly configured view object, then in the identity inspector, deleted the bad custom class displayed for it (by backspacing and hitting return). That took care of the problem.
In my case, the custom class should be assigned to to the view controller, and not the view object managed by the controller.
I hit a similar issue when I changed the default Xcode project's UIViewController subclass to instead be a subclass of UITableViewController. (I made this change in the class source file, nothing to do with Storyboard).
I then went and typed my new class name into the IB "Class" field of the default "view" in the Storyboard. It would not autocomplete my class name, and then gave the Unknown class in Interface Builder file error when run.
The solution was to delete the default UIViewController object from the Storyboard, then add a new UITableViewController. Then, set that object's Class in IB to be your custom class.
It seems like the original question may be hitting this issue, as the first screenshot's class is ...ViewController and the second is ...TableViewController.
I've encountered the same issue and got it fixed. Reading this question gave me an idea to check the Identity Inspector further more and I found that the class Module should be inherit from target instead from a None module as I had.
Try checking the Inherit Module From Target checkbox and rebuild.
Hope it can help someone, obviously your problem has been solved since it was published in 2014.

Custom control in reference does not render correctly

I have made a custom control (round button with a fixed image) and tested that it works. However, I would like to reuse this particular control in other projects and hence thought of making a class library out of it. However, when I try to get the custom control to show in my other applications, the icons does not show even though the button responds to clicks.
I have tried to build the icon in the class library projects as Content and Resources and test but to no avail. (of course, I change the addressing of the icon in the code when I updated its build icon). At the moment, i have decided to leave the icon /icons/myimage.png to be built as Content. And, in the class library code (XAML), i am accessing it as "/icons/myimage.png".
So, would anyone have an idea on how I could get the round button to render properly in my projects? How should I build the class library project?
I would't make a graphics part of my class library, because most likely in the future you will need to customize it, so what I suggest is to make the following property in your custom module and set the image where you use it:
public ImageSource ButtonImage {get { return <button image>; } set { <set button image>; } }
I experimented a bit and found the solution. The idea is to use embedded resource to store the image in the dll. And then for loading it by the CustomControl, one can use constructs like this:
BitmapImage img = new BitmapImage();
img.SetSource(Assembly.GetExecutingAssembly().GetManifestResourceStream("MyLib.icons.my_icon.png"));
MyLib here is the name of the assembly for the class library. icons is the folder where the resource is kept in the assembly.

Resources