I created custom class LoginView.cs UIView For username and password added the loginButton.
now I added UIView Call into my LoginViewController.cs Class
When i build and run the application it shows the login box, two text fields and a button. The actions on the textfield are not working. When the textbox has focus the keyboard doesn't load
This is my custom View class for loginview.cs
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace DemoHouse
{
class LoginView : UIView
{
UIView view_Login;
UITextField txt_username;
public readonly UITextField txt_password;
public readonly UIButton btn_Login;
public LoginView (string loginView){
float frame = UIScreen.MainScreen.Bounds.Width;
Add (view_Login = new UIView (new RectangleF (20, 60,frame-40, 200)) {
BackgroundColor = UIColor.Red,
});
float subFrame = view_Login.Bounds.Width;
view_Login.AddSubview(txt_username = new UITextField (new RectangleF (20, 20, subFrame-40, 31)){
BackgroundColor = UIColor.White,
});
view_Login.AddSubview(txt_password = new UITextField (new RectangleF (20, 70, subFrame-40, 31)){
BackgroundColor = UIColor.White
});
view_Login.AddSubview (btn_Login = new UIButton (new RectangleF (20, 120, 60, 31)) {
BackgroundColor = UIColor.Blue
});
}
}
}
This is LoginViewController.cs
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace DemoHouse
{
public partial class LoginViewController : UIViewController
{
LoginView loginView;
UIScrollView scrollView;
public override void DidReceiveMemoryWarning (){
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
#region View lifecycle
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
loginView = new LoginView("LoginView");
View.AddSubview (loginView);
// Perform any additional setup after loading the view, typically from a nib.
}
Let me know if something is wrong.
Is this the correct approach?
I do not want to use storyboard and xib in my application.
#All
Thanks in advance.
Might be a silly solution, but add a tap gesture to the button.
login_btn.UserInteractionEnabled = true;
login_btn.AddGestureRecognizer (new UITapGestureRecognizer(()=>{
//Action In HERE
}));
The keyboard popping up is a native functionality, so I am in awe you managed to break it. Maybe you should try not to condensate your code so much. It makes for less lines of code, but also causes readability and complexity to increase. Also, why not merge both classes? You already have a ViewController class. Try something like this:
public partial class LoginViewController : UIViewController
{
private UIScrollView scrollView;
private UITextField txt_username, txt_password;
private UIButton btn_login;
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
/*Depending on what else is on the screen, you can hard-code the
x, y, width and height, but in all other cases, use this:*/
scrollView = new UIScrollView (this.View.Bounds);
txt_username = new UITextField (new RectangleF (5, 5, 50, 25));
//Change other properties of the UITextfield to your liking here.
txt_password = new UITextField (new RectangleF (5, 35, 50, 25));
//Change other properties of the UITextfield to your liking here.
btn_login = new UIButton (new RectangleF (5, 65, 50, 25));
btn_login.TouchUpInside += Login;
//Change other properties of the UIButton to your liking here.
this.View.AddSubview (scrollView);
scrollView.AddSubviews (new UIView[]{txt_username, txt_password, btn_login});
}
void Login (object sender, eventargs e)
{
//Do something on button click
}
}
Keep in mind that with this solution, you won't actually be able to scroll down with the scrollView, because the scrollView.ContentSize is not set. You could implement a method, where the framesizes of all controls are set. You call this method when changing orientation (in the ViewDidRotate method). You can also add the scrollView.ContentSize in this method.
I hope this information helps. Good luck!
Related
I have created a custom control derived from Panel.
Everything works fine, except that in designer my control is only redrawn when it loses focus.
What am I missing?
Here is the code of CustomControl.cs
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Picwing
{
public partial class xPanel : Panel
{
private SizeF textSize;
public xPanel() {
InitializeComponent();
}
[Browsable(true)]
public override string Text {
get { return base.Text; }
set { base.Text = value; }
}
protected override void OnPaint(PaintEventArgs pe) {
base.OnPaint(pe);
textSize = pe.Graphics.MeasureString(Text, Font);
pe.Graphics.DrawRectangle(new Pen(ForeColor, 1), pe.ClipRectangle.X, pe.ClipRectangle.Y + textSize.Height / 2, pe.ClipRectangle.Width - 1, pe.ClipRectangle.Height - textSize.Height / 2 - 1);
pe.Graphics.FillRectangle(new SolidBrush(BackColor), 5, 0, textSize.Width, textSize.Height);
pe.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), pe.ClipRectangle.X + 6, pe.ClipRectangle.Y);
}
}
}
This is a print screen taken after moving label1 inside xPanel1, before it loses focus.
Your problem is because of using pe.ClipRectangle while painting on control.
Don't use pe.ClipRectangle. Use DisplayRectangle or ClientRactangle instead, based on your requirement.
When you draw in pe.ClipRectangle bounds, as you can see, the drawing will be done on the smallest invalidated part of your control.
Note:
You don't need to have InitializeComponent(); in constructor unless you use designer of your panel component to add some other components to it.
If you used DisplayRectangle, then in the FillRectangle method, instead of 0,5 use DisplayRectangle.X + 5, DisplayRectangle.Y.
If you are trying you draw a custom GroupBox, you can take a look at Custom GroupBox BackColor to Transparent
I'm new to ios development. I am trying to create a vertical ScrollView in a Xamarin iOS application.
Below is my code for a horizontal ScrollView
using System;
using UIKit;
using Foundation;
using CoreGraphics;
using System.Collections.Generic;
namespace TestApp
{
public partial class ViewController : UIViewController
{
public ViewController (IntPtr handle) : base (handle)
{
ScrollingButtonsController ();
}
UIScrollView scrollView;
List<UIButton> buttons;
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
//MyScrollView.scrollEnabled=YES;
//MyScrollView.contentSize= CGSizeMake(CGFloat.width, CGFloat.height);
//end
nfloat h = 50.0f;
nfloat w = 50.0f;
nfloat padding = 10.0f;
nint n = 100;
scrollView = new UIScrollView {
Frame = new CGRect (0, 100, View.Frame.Height, h + 2 * padding),
ContentSize = new CGSize ((w + padding) * n, h),
BackgroundColor = UIColor.Red,
AutoresizingMask = UIViewAutoresizing.FlexibleWidth
};
for (int i=0; i<n; i++) {
var button = UIButton.FromType (UIButtonType.RoundedRect);
button.SetTitle (i.ToString (), UIControlState.Normal);
button.Frame = new CGRect (padding * (i + 1) + (i * w), padding, w, h);
scrollView.AddSubview (button);
buttons.Add (button);
}
View.AddSubview (scrollView);
//UIScrollView scrollView;
//scrollView = new UIScrollView (
// new CGRect (0, 0, View.Frame.Width, View.Frame.Height));
// View.AddSubview (scrollView);
}
public void ScrollingButtonsController ()
{
buttons = new List<UIButton> ();
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
}
}
I want to create a vertical scrollview and add some scrollable Text Views. Any idea on how can to do this?
I would be grateful if you can specify in detail how can I get the elements in my Main.storyboard file with structure scheme as per below to scroll:
-Scroll View
--label
---Image View
---Text View
--label
---Image View
---Text View
--label
---Image View
---Text View
--label
---Image View
---Text View
--label
---Image View
---Text View
and more...
You need to set ScrollView Content Size Height, larger than it's frame height.So it will scroll up/down. Width of scroll view should be the same as its content width, so it won't scroll right/left.
I was searching for this. I used many tutorials both with and without code. The best way to do the scrolling is the following:
Add the scrollview (left, right, up, down constraints)
Add whatever you want
The tricky part is to set 2 constraints:
1) horizontal space to container, where container is the scroll view (do this with you wider element)
2) vertical space to container, where container is the scroll view (do this with your last element)
While your screen becomes taller, the vertical constraint will increase your scroll view. No code needed, just the proper constraints.
In your example you have to:
set up, left and right constraints to your first label
add vertical constraints amongst all your labels
add the final vertical constrain between your final textview and the scrollview (the textview is possible to need a height constraint)
If your elements don't fit the screen in Xcode, use freeform size to make your controller bigger (this applies only to xcode, not on your actual program)
I'm trying to style the UINavigationBar in Xamarin with MonoTouch. In the constructor of the UIViewController I tried the following:
//this.NavigationController.NavigationBar.TintColor = UIColor.Magenta;
UINavigationBar.Appearance.TintColor = UIColor.Yellow;
But if I try to run this in the simulator there is nothing changed. Where should I place this code? How do I use a RGB color (with UIColor.FromRGB (0, 127, 14)?) Is my code correct?
My Solution:
//AppDelegate.cs
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
public static UIStoryboard Storyboard = UIStoryboard.FromName ("MainStoryboard", null);
public static UIViewController initialViewController;
// ...
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
initialViewController = Storyboard.InstantiateInitialViewController () as UIViewController;
UINavigationBar.Appearance.SetTitleTextAttributes (
new UITextAttributes () { TextColor = UIColor.FromRGB (0, 127, 14) });
window.RootViewController = initialViewController;
window.MakeKeyAndVisible ();
return true;
}
}
Assuming that you're developing for iOS7 you need to set BarTintColor.
UINavigationBar.Appearance.BarTintColor = UIColor.Red;
UINavigationBar.Appearance.BarTintColor = UIColor.FromRGB(0, 127, 14);
see: How to change UINavigationBar background color from the AppDelegate
Put this code in AppDelegate.cs
Try this ..
NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor darkGrayColor], UITextAttributeTextColor, [UIColor whiteColor], UITextAttributeTextShadowColor, nil];
[[UINavigationBar appearance] setTitleTextAttributes:textTitleOptions];
Or you can refer more from
IOS 7 Navigation Bar text and arrow color
You should specific the UIViewController, like:
viewController.navigationBar.tintColor = [UIColor yellowColor];
or in UIViewController:
self.navigationBar.tintColor = [UIColor yellowColor];
I am trying to create a custom UIButton which extends from UIButtonType.RoundedRect.
My added functionality is working, but there is an issue with the initial rounded border state of my button. The border of my extended button is not drawn until after it has been tapped.
Update (January 24th 2013): Added the result of red background test, as requested by Richard Marskell, which concludes only the label of the button is drawn. BackgroundColor = UIColor.Red;
Below is my source code for creating my custom button.
public class TestView : UIView
{
public TestView(IntPtr p) : base(p) { }
public TestView(RectangleF bounds)
{
Frame = bounds;
BackgroundColor = UIColor.White;
UIButton button1 = new UIButton(UIButtonType.RoundedRect);
button1.Frame = new RectangleF(20,20,100,50);
button1.SetTitle("Button 1", UIControlState.Normal);
AddSubview(button1); // Drawn Correctly
MyButton button2 = new MyButton();
button2.Frame = new RectangleF(20,90,100,50);
button2.SetTitle("Button 2", UIControlState.Normal);
AddSubview(button2); // Only drawn correctly after Tap
// EDIT: Added to test Miguel's theory
UIButton button3 = UIButton.FromType(UIButtonType.RoundedRect);
button3.Frame = new RectangleF(20,160,100,50);
button3.SetTitle("Button 3", UIControlState.Normal);
AddSubview(button3); // Drawn Correctly
}
}
public class MyButton : UIButton
{
public MyButton() : base(UIButtonType.RoundedRect) { }
}
I'm just not sure how to force the border to be drawn correctly on loading of the view.
I don't need a button of type UIButtonType.Custom, as I don't want to style the button myself.
When I debug I the type of MyButton is correctly set to UIButtonType.RoundedRect.
The UIButton base properties of MyButton (button2) match the properties of the UIButton instance (button1).
How can I resolve this issue?
Update (January 31st 2013): Herman Schoenfeld provided a suitable solution for this bug.
This works
public class MyButton : UIButton
{
public MyButton() : base(UIButtonType.RoundedRect) { }
public override RectangleF Frame {
get {
return base.Frame;
}
set {
var temp = TranslatesAutoresizingMaskIntoConstraints;
TranslatesAutoresizingMaskIntoConstraints = false;
var constraints = new [] {
NSLayoutConstraint.Create(this, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, value.Width),
NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, value.Height)
};
AddConstraints(constraints);
SizeToFit();
RemoveConstraints(constraints);
base.Frame = value;
TranslatesAutoresizingMaskIntoConstraints = temp;
}
}
}
This is only a workaround, it appears to be a bug. The SizeToFit() fixes the issue, the other code maintains the frame.
I have created a simple custom panel using ContainerControl as my base. I've added custom properties to create borders and gradient backgrounds. If I override OnPaint and OnPaintBackground all child controls of the parent inherit the gradient and border styles. As a work around I have used the parents BackgroundImage property which works fine but has a few random quirks. There has to be a better way of approaching this issue but I have found no solution. Are there any Window API functions via Interop or other C# methods to fix this? If so please provide an example.
EDIT! Here is the style being copied (ugly example but makes the point):
EDIT 2! Here is a simple hard-coded ContainerControl without all the properties, designer attributes, etc.
public class Container : ContainerControl
{
protected override void OnPaintBackground( PaintEventArgs e )
{
using ( var brush = new LinearGradientBrush( e.ClipRectangle, Color.Red, Color.Blue, LinearGradientMode.Vertical ) )
{
e.Graphics.FillRectangle( brush, e.ClipRectangle );
}
}
}
If a Label control is created with its BackColor property set to Color.Transparent, it will end up calling its parent's OnPaintBackground() implementation.
If you modify Jon's example like this:
var label = new Label {
Text = "Label",
Location = new Point(20, 50),
BackColor = Color.Transparent
};
Then you will reproduce the issue.
There is an easy workaround, however. The problem comes from the way you're creating the linear gradient brush. Since you're passing e.ClipRectangle to its constructor, the shape of the gradient will vary depending on the control being rendered (container or label). On the other hand, if you pass the ClientRectangle of the container, then the gradient will always have the same shape and the result should be what you're looking for:
protected override void OnPaintBackground(PaintEventArgs e)
{
using (var brush = new LinearGradientBrush(ClientRectangle,
Color.Red, Color.Blue, LinearGradientMode.Vertical)) {
e.Graphics.FillRectangle(brush, e.ClipRectangle);
}
}
The result is:
Initialize the properties on control create/load
Then "INVALIDATE" the control to force a redraw of the control
I can't reproduce this simply on my Windows 7 machine - which suggests it may be one of the properties you've set in the designer. Short but complete program:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class GradientContainer : ContainerControl
{
protected override void OnPaintBackground(PaintEventArgs e)
{
using (var brush = new LinearGradientBrush(e.ClipRectangle,
Color.Red, Color.Blue, LinearGradientMode.Vertical))
{
e.Graphics.FillRectangle(brush, e.ClipRectangle);
}
}
}
class Test
{
static void Main()
{
var label = new Label {
Text = "Label",
Location = new Point(20, 50)
};
var container = new GradientContainer {
Size = new Size(200, 200),
Location = new Point(0, 0),
Controls = { label }
};
Form form = new Form {
Controls = { container },
Size = new Size(300, 300)
};
Application.Run(form);
}
}
And the result: