I edited a storyboard in Xcode's Interface Builder, and assigned the View Controllers from Interface Builder.
Now when I attempt to compile the project I receive the following compiler error:
/absolute/path/to/project/MyProject.iOS/CSC: Error CS2011: Error opening response file '/absolute/path/to/project/MyProject.iOS/Views/Root/RootController.cs' (CS2011) (MyProject.iOS)
/absolute/path/to/project/MyProject.iOS/CSC: Error CS2011: Error opening response file '/absolute/path/to/project/MyProject.iOS/Views/Root/RootController.designer.cs' (CS2011) (MyProject.iOS)
I don't know if this could be related, but when I create the ViewController from Visual Studio for Mac [Community] (7.2.2 build 11) it also creates a .xib file for the ViewController, that I just delete as I only want the ViewController.
Anyway, is there anything I should do differently when editing storyboards from Xcode? Or is there something I'm missing when creating a new UIViewController from Visual Studio?
Here is the file Visual Studio generates for the UIViewController
public partial class RootController : UIViewController
{
public RootController() : base("RootController", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
Ok, I'm going to post the answer to this as I just found out what was causing it.
In my solution I have my Views folder named #Views so it sits at the top of the folder structure. Visual Studio doesn't seem to like that name #Views specifically the # and thus strips it out, which makes it an invalid path when when it goes to look for the file.
So it's my poor choice of naming that caused my own issue.
Related
If I am using Visual Studio for Mac it has this field in the designer.
It creates a property in the View.cs file that allows me to bind to it.
I found a similar section in xcode (that is what rider opens up) and it only has these options. No field for Name.
This name field is not what shows up on the button label. I know how to set that.
I would much rather use Rider than Visual Studio for mac. If I have to constantly jump back and forth this would obviously be a problem.
EDIT: From what I can tell, it seems to edit the View.designer.cs.
It has this comment though. How would I be able to edit this from Rider?
// WARNING
//
// This file has been generated automatically by Visual Studio from the
outlets and
// actions declared in your storyboard file.
// Manual changes to this file will not be maintained.
//
This was what it looks like on default with a new MvvmCross project
using Foundation;
using System;
using System.CodeDom.Compiler;
namespace HelloCrossPlatform.iOS.Views
{
[Register ("FirstView")]
partial class FirstView
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UILabel Label { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UITextField TextField { get; set; }
void ReleaseDesignerOutlets ()
{
if (Label != null) {
Label.Dispose ();
Label = null;
}
if (TextField != null) {
TextField.Dispose ();
TextField = null;
}
}
}
}
Here is what it looks like when I add the name property to the button in Visual Studio for Mac with the Designer
using Foundation;
using System;
using System.CodeDom.Compiler;
namespace HelloCrossPlatform.iOS.Views
{
[Register ("FirstView")]
partial class FirstView
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UILabel Label { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UIButton SayHelloButton { get; set; }
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UIKit.UITextField TextField { get; set; }
[Action ("UIButtonDZD114An_TouchUpInside:")]
[GeneratedCode ("iOS Designer", "1.0")]
partial void UIButtonDZD114An_TouchUpInside (UIKit.UIButton
sender);
void ReleaseDesignerOutlets ()
{
if (Label != null) {
Label.Dispose ();
Label = null;
}
if (SayHelloButton != null) {
SayHelloButton.Dispose ();
SayHelloButton = null;
}
if (TextField != null) {
TextField.Dispose ();
TextField = null;
}
}
}
}
Is rider even a good tool to use with Xamarin? I'm getting disappointed they even market it as an option. Really questioning my subscription to JetBrains.. Vscode seems to work just as well as Webstorm which is the only other product I work with from them.
Rider does NOT have a special designer for .xib and .storyboard UI files. We (the Rider team) think we will not be able to implement as good (and actual) UI designer as the native xcode is. So the main scenario to work with Xamarin macios UI in Rider - use xcode interface builder.
You can check the apple documentation about outlets generating:
https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ConnectingObjectstoCode.html
This is a brief description how to do it in xcode 11 with default settings.
Split UI editor into designer and source parts
Ctrl+Click the control you want to bind and drag it into the code. Important note: use .h files to create new actions and outlets, Rider analyzes .h files to build a public API model.
Now you can enter the name of the control it the binding will be created. You will see corresponding outlets in objc code.
Maybe it is not that straightforward so I will try to explain how it works internally.
Xamarin macios project is an (almost) regular .NET C# project. So to allow you edit UI in the xcode, Rider (and VS actually) do some magic. It takes the .NET project and:
Creates the corresponding xcodeproj (pbxproj and friends) project in obj\xcode folder with specific settings and configurations.
Copies all content like views, plist files, images and so on.
Looks for all ViewController types. For each of them Rider generates objc class with actions and outlets.
Opens xcode and the generated project into.
When you have made some changes in that generated project and go back to Rider, it tries to apply all changes:
Copies all changed content files back into .NET project
Updates settings
Parses objc files and regenerate *.designer.cs files for view controllers. For all these files you will see this generated header (can be changed in the future):
// WARNING
//
// This file has been generated automatically by Rider IDE
// to store outlets and actions made in Xcode.
// If it is removed, they will be lost.
// Manual changes to this file may not be handled correctly.
//
To control xcode synchronization process and see whats going on and see what errors occur you can use a special Rider toolwindow: xcode console. It is shown each time you open a project in xcode:
Instead of conclusion: Rider's team tries to provide good experience for Xamarin Developers, even better then VS for Mac. So are working on support some Xamarin parts (Xamarin Forms Hot Reload in the 2020.1) so feel free to share your troubles in our public issue tracker:
https://youtrack.jetbrains.com/issues/RIDER?q=Technology:%20Xamarin%20
I downloaded a copy of the current Xamarin Forms master branch, compiled it, and then I added these compiled assemblies as references to a test project:
Xamarin.Forms.Core
Xamarin.Forms.Platform
Xamarin.Forms.Platform.Android
Xamarin.Forms.Xaml
The test project was created using the Visual Studio Xamarin Forms project template, the only thing I modified is the references in the Core.csproj and Android.csproj to point to the compiled assemblies.
I used the first 3 from the bin\debug\ folder of the Xamarin.Forms.Platform.Android project, and the last one from the Xamarin.Forms.Xaml bin\debug folder.
I run the test project, and it runs fine, I can see the label from the default generated code "Welcome to Xamarin Forms!"
Next, I just modified the MainPage like this:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new ContentPage());
}
}
When I run the app, it gives me an error
System.ArgumentException: element is not of type Xamarin.Forms.View
Parameter name: element
thrown on this line:
void IVisualElementRenderer.SetElement(VisualElement element)
{
if (!(element is TElement))
throw new ArgumentException("element is not of type " + typeof(TElement), nameof(element));
SetElement((TElement)element);
}
which is strange.
The type of the element is Xamarin.Forms.NavigationPage and the stack trace is
Can someone help me running the test project with the compiled assemblies?
UPDATE #1:
The 2nd entry in the call stack shows that it's not able to get the registered renderer(NavigationPageRenderer) for the NavigationPage element and instead it's creating a default renderer(DefaultRenderer), which can't handle the type of element(NavigationPage) so it's throwing the exception I see.
So it appears that for NavigationPage, it doesn't find its renderer(NavigationPageRenderer) in the Registrar.
public static IVisualElementRenderer CreateRenderer(VisualElement element)
{
UpdateGlobalContext(element);
IVisualElementRenderer renderer = Registrar.Registered.GetHandler<IVisualElementRenderer>(element.GetType()) ?? new DefaultRenderer();
renderer.SetElement(element);
return renderer;
}
My feeling is there's a build step I'm not aware about when building Xamarin Forms.
Its crashing as you are calling InitializeComponent on something which doesn't derive from a Forms.Page (i.e. ContentPage etc).
The application itself is not a Page, if you had a page, lets call it 'MyCustomPage' which has some Xaml behind the class would look something like this:
public partial class MyCustomPage : ContentPage
{
public MyCustomPage()
{
InitializeComponent ();
// Some other setup...
}
}
Then in your App constructor you would call
MainPage = new MyCustomPage();
Since you are creating a blank content page from the root of your app, you do not need to call InitializeComponent.
Hope this helps.
You also need to reference
Xamarin.Forms.Platform.Android (Forwarders)
from your Android project.
Autocomplete isn't working for me when accessing members from a class extension in Xcode (6.3.2).
I made a UIColor extension, and I am accessing them via UIColor().sampleExtendedColorName(), and it does not show up while I'm typing. Autocomplete works for everything other than this. Is there a setting I can change?
extension UIColor{
func sampleExtendedColorName() -> UIColor {
return UIColor(red:200/255, green:100/255, blue:120/255, alpha:1.0)
}
}
Update (new info):
So autocomplete is working if I access the UIColors from a ViewController that directly subclasses UIViewController, but if I subclass a custom CustomViewController that is a subclass of UIViewController, autocomplete doesn't show up for some reason.
Checking all the Target Memberships is working fine. If you don't know where the Target Membership is,
Go to your swift file (Eg: ViewController.swift)
On the right side in the Utilities panel, Click file inspector
You can see Target Membership there.
Check all the fields.
Figured it out, issue was on my ColorExtension.Swift file in my Xcode project. I needed to check all the Target Memberships.
I am trying to build a custom TableViewCell, and so far I have created a xib file and laid it out in XCode designer. However, I cannot find my class in the drop down in identity inspector, and I cannot locate the generated class when in content assister.
Is there something beyond creating the xib in MonoDev to make my designer class available to XCode designer?
The (C#) class needs to have a Register attribute:
[Register ("MyClass")]
public class MyClass : UITableViewCell
{
}
Per Xamarin support:
When creating a custom UITableViewCell (and wanting to use the
designer), you have to use a bit of a "hacky" process to get the
code-behind file to work. You are going to want to add the class as a
iPhone (or iPad or Universal) UIViewController, change the superclass
of the class you just created to UITableViewCell. Make your changes in
the Xcode designer (delete view and add UITableViewCell), and then
make your changes in your code-behind file.
There is a great tutorial on how to do this here:
http://www.arcticmill.com/2012/05/uitableview-with-custom-uitableviewcell.html
So I have started to play around with MonoTouch.
OS X 10.6.8
MonoTouch v4.0.3
MonoDevelop v2.4.2
Mono Framework v2.10.2
XCode v3.2.6
So I'm having problems with the outlets. Creating a simple one page program, editing the XIB in Interface Builder to add outlets, they are properly inserted as class properties into the MainWindow.xib.designer.cs like so:
[MonoTouch.Foundation.Connect("btnClickMe")]
private MonoTouch.UIKit.UIButton btnClickMe {
get {
this.__mt_btnClickMe = ((MonoTouch.UIKit.UIButton)(this.GetNativeField("btnClickMe")));
return this.__mt_btnClickMe;
}
set {
this.__mt_btnClickMe = value;
this.SetNativeField("btnClickMe", value);
}
}
However, when I create a multi page navigation based project in MonoDevelop and create outlets for my Views, they are not inserted into the *.designer.xib.cs files.
This is probably some noob beginner mistake, but what could I be doing wrong?
Well, after fiddling around, I found out the issue.
I added my outlets in the View class in the Library Windows.
The correct place to add them is in the File's Owner class.
#Dimitris, add your comment as an answer, and I can accept it as an answer.