I am developing an app using Xamarin.iOS. It will have a lot of screens that I cannot design using Main.StoryBoard, so I have to design every ViewController separately. Right now I have 2 screens: ViewController.cs and InProgress.cs. I have wrapt the ViewController.cs inside a NavigationController in Main.StoryBoard. Below is the code:
ViewController.cs (ViewDidLoad)
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
//change the navigation bar controller
this.NavigationController.NavigationBar.BarTintColor = UIColor.FromRGB (26f / 255f, 56f / 255f, 100f / 255f);
this.NavigationController.NavigationBar.TitleTextAttributes = new UIStringAttributes()
{
ForegroundColor = UIColor.White
};
NavigationController.NavigationBar.BarStyle = UIBarStyle.Black;
//change the layout of collectionView Layout
//initialize the data
sectionCategories = new List<SectionCategory>();
sectionCategories.Add(new SectionCategory("Lajme", "http://www.ikub.al/media/iOS/lajme.jpg"));
......
sectionCategories.Add(new SectionCategory("Shtypi i dites", "http://www.ikub.al/media/HP/shtypi.jpg"));
sectionGrid.RegisterClassForCell(typeof(SectionViewCell), SectionViewCell.CellID);
sectionGrid.Source = new SectionViewSource (sectionCategories,this);
}
When I click an item of the sectionGrid it pushes a new ViewController in the stack.
var soonVC = new InProgress ("InProgress");
soonVC.Title = "InProgress";
owner.NavigationController.PushViewController(soonVC, true);
The InProgress screen has the a .cs file, a .desigener.cs file and .xib file like the following:
public partial class InProgress : UIViewController
{
String section;
public InProgress (String text) : base ("InProgress", null)
{
section = text;
}
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.
}
}
[Register ("InProgress")]
partial class InProgress
{
[Outlet]
[GeneratedCode ("iOS Designer", "1.0")]
UILabel labelComingSoon { get; set; }
void ReleaseDesignerOutlets ()
{
if (labelComingSoon != null) {
labelComingSoon.Dispose ();
labelComingSoon = null;
}
}
}
But I have 2 problems:
I have to access the navigation bar of InProgress screen in order to change the back item, navigation style, text color, back button text, add new item etc.
When I have designed the layout in .xib file I have the label in the center, but in reality it's not in the center of the screen because it does not take into consideration the height of the navigation bar, so some layout may be hidden under the NavigationBar.
I have tried some piece of code like
soonVC.NavigationItem.LeftBarButtonItem.Title = " dsf";
but it gives me a null object.
Any suggestion for both the problems.
InProgress.xib
In your InProgress class you can set the back button text like so :
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
UIBarButtonItem newBackButton = new UIBarButtonItem("dfs",UIBarButtonItemStyle.Plain, (sender,args) => NavigationController.PopViewController (true));
NavigationItem.SetLeftBarButtonItem (newBackButton, false);
// The line below will move the search bar below the nav bar
NavigationController.NavigationBar.Translucent = false;
}
As for the next question:
When I have designed the layout in Xib file I have the label in the
center, but in reality its not in the center of the screen because it
does not take into consideration the height of the navigation bar, so
some layout may be hidden under the Navigation bar.
Are you using Autolayout? All you need to do is add a constraint to center vertical and it should center in the view. Are you able to upload your xib? if you are not using Autolayout you will just have to adjust for the Navigation Controller.
UPDATE
If you set your navbar to not be translucent it will go below the nav bar. You can set this in the InProgress class or when you here in the storyboard:
I have also added the autolayout constraints to your xib to center your label here is the xib xml:
HTH.
Related
I want to create a custom ActionBar library. The user that wants to use the ActionBar can insert actions, that will get rendered by ng-content.
When the ActionBar is too small to display all the actions I want to display a dropdown with the remaining actions that don't fit into the bar.
I got a ResizeObserver that handels the hiding/showing.
Calling the ActionBar
<action-bar>
<action-bar-left>
// user action to display in the action bar
<button class="btn accept" (click)="onActionBarBtnClick('accept')"></button>
</action-bar-left>
</action-bar>
ActionBarLeft.component.html
<ng-content></ng-content>
<button #dropDownButton class="action-bar-not-visible-elements" (click)="showOverlay()" [ngClass]="elementsHidden ? '' : 'action-bar-dropdown-hidden'">
<div class="action-bar-overlay-container">
<div [ngClass]="overlayShown ? 'action-bar-overlay-shown' : ''" #overlay>
<!--actions that don't fit will get rendered here-->
</div>
</div>
</button>
Currently I am using the Renderer2 to move the item from the ActionBar to the Dropdown and vice-versa. That works quiet well except that it dosn't get the order quiet right. When I resize the ActionBar many times the actions are not in the same order as initialy.
ActionBarLeft.component.ts
constructor(private _host: ElementRef, private _renderer: Renderer2, private _ngZone: NgZone) { }
public ngAfterViewInit(): void {
this._ngZone.runOutsideAngular(() => {
this._resizeObserver = new ResizeObserver((_entries, _observer) => {
this.displayActions();
});
this._resizeObserver.observe(this._host.nativeElement);
});
}
private displayActions(): void {
this.elementsHidden = false;
this.resetOverlay();
const hostElem = this._host.nativeElement;
let availableWidth = this._host.nativeElement.clientWidth - this._reservedDropDownSpace;
const notVisible = [];
for (const el of hostElem.children) {
availableWidth -= el.clientWidth;
if (availableWidth < 0) {
if (el.className.startsWith("action-bar-not-visible-elements")) {
continue;
}
this.elementsHidden = true;
notVisible.push(el);
}
}
for (const el of notVisible) {
this._renderer.appendChild(this._overlay.nativeElement, el);
}
}
private resetOverlay(): void {
for (const child of this._overlay.nativeElement.children) {
this._renderer.insertBefore(this._host.nativeElement, child, this._dropDownButton.nativeElement);
}
}
The Renderer2 is quiet comfortable because I can get the size of the ActionBar elements so that I can precisely determine which element fits into the bar.
I do not want to use the Render2 because of the DOM manipulation and because it dosn't keep the order of the actions.
If there is no better solution and someone knows how to keep the order, I would stickt to the Renderer2.
I tried StructuralDirectives:
viewContainerRef.createEmbeddedView(templateRef);
The problem is, that I can't get the width of the rendered Element that way.
What I want to do is:
Let the user add ActionBarActions inline
Determine which actions fit into the ActionBar
display the other actions that don't fit in a dropdown
when resizing the window, it should be recalculated if the actions fit into the ActionBar
There is an ActionBarRight, but it is not interesting in this context.
I am currently working with windows phone 8.1 [RT] application , In my application I have hide Grid Visibility from class.
For that I have create one public method on cs page
public void HideCancelButton()
{
grdCancle.Visibility = Visibility.Collapsed;
bdrCancel.Visibility = Visibility.Collapsed;
Debug.WriteLine("hide button");
//UpdateLayout();
}
and calld that method in following manner in helperClass.cs
MainPage mypage = new MainPage();
mypage.HideCancelButton();
it will debug "hide button" but doesn't hide grid
I have also use
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() =>{});
It won't hide the grid because you are not referencing the MainPage that is currently showing.
You should get the reference to the main page wherever you are calling the HideCancelButton method.
In your case the easiest solution will be doing something like this (considering you are not calling the method from the MainPage class itself.
Frame rootFrame = Window.Current.Content as Frame;
MainPage mainPage = rootFrame.Content as MainPage;
if(mainPage != null)
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync
(
Windows.UI.Core.CoreDispatcherPriority.Normal,
() => { mainPage.HideCancelButton(); }
);
}
i am working on GWT to make web application but now i need to make my web applications in Responsive design but GWT not support Responsive Design please help me.
GWT supports responsive design just like any other widget toolkit (OK, that's not exactly true, there are probably widget toolkits that do a better job): do your layout with HTMLPanel, FlowPanel, SimplePanel and responsive CSS, or go the active layout route with layout panels and doing calculations in your code (or in a custom layout panel).
You can make your layout responsive using CSS media queries.
For example, to make dialog boxes occupy 90% of the available horizontal space on devices that have screen size up to 640px, one can wrap the style inside #media block like this:
#media all and (max-width: 640px) {
.gwt-DialogBox {
width: 90%;
}
}
Unfortunately (as of today) GWT compiler does not support media CSS, so the code above will fail if you use it in conjunction with CssResource.
One of the approaches to this problem is to split your CSS resources into two files.
All default (desktop) CSS styles would go to the first file (e.g. main.css), and all your mobile overrides would go to the second file (e.g. mobile.css).
Note that style names that you want to override for mobile need to be tagged as #external in the main.css to avoid name obfuscation by gwt compiler.
main.css:
#external .mainNorthPanel;
.mainNorthPanel {
position: fixed;
top: 0px;
}
mobile.css:
#media all and (max-width: 640px) {
.mainNorthPanel {
position: absolute;
top: -3em;
}
}
In your application ClientBundle, use main.css in conjunction with your CssResource interface, and define the mobile file as an external resource:
public interface MyBundle extends ClientBundle {
public interface MainStyles extends CssResource {
String mainNorthPanel();
}
#Source("css/main.css")
MainStyles css();
#Source("css/mobile.css")
TextResource mobile();
}
And finally inject your external CSS resource somewhere in the module initialization:
String mobileCss = myBundle.mobile().getText();
StyleInjector.injectAtEnd(mobileCss)
For the full working example, take a look at this JavaWorld post that just came out recently:
http://www.javaworld.com/article/2842875/java-web-development/responsive-web-design-with-google-web-toolkit.html
It covers some basic concepts such css-based responsive views, dialogs, and menus.
And there is a little proof of concept on github:
https://github.com/cuppafame/gwt-responsive
In addition to what Thomas said you can look into gwt-bootstrap. They have a custom DataGrid widget that can be shown or hidden based on breakpoints (tablets, phones, etc).
If you actually want to hide and show columns based on available size you extend the DataGrid and do something along this lines:
ResponsiveDataGrid extends DataGrid<myDTO> {
private final Column<myDTO,String> column1;
private final Column<myDTO,String> column2;
private Boolean isCompact;
public ResponsiveDataGrid(int pageSize, Resources resources,ActionCell.Delegate<myDTO> actionDelegate) {
super(pageSize, resources,new EntityProxyKeyProvider<myDTO>());
initColumns();
}
private void initColumns() {
// init your columns
}
private void updateColumns() {
int columnCount = getColumnCount();
for (int i =columnCount-1;i>=0;i--) {
removeColumn(i);
}
removeUnusedColGroups();
if (isCompact) {
// show columns for compact size
}
else {
// show all columns
}
}
#Override
protected int getRealColumnCount() {
return getColumnCount();
}
// WORKAROUND for some sizing issues in DataGrid
private void removeUnusedColGroups() {
int columnCount = getColumnCount();
NodeList<Element> colGroups = getElement().getElementsByTagName("colgroup");
for (int i = 0; i < colGroups.getLength(); i++) {
Element colGroupEle = colGroups.getItem(i);
NodeList<Element> colList = colGroupEle.getElementsByTagName("col");
for (int j = colList.getLength()-1;j>=0; j--) {
colGroupEle.removeChild(colList.getItem(j));
}
}
}
#Override
public void onResize() {
super.onResize();
if (!isAttached()) {
return;
}
// or whatever breakpoint you want to support
boolean isNewCompact = (getOffsetWidth() < 800);
if (isCompact == null || isNewCompact != isCompact) {
isCompact = isNewCompact;
updateColumns();
}
}
}
/*The best way to do responsive web with is to use Timer class and Window class in GWT as Gwt does not responsive web at the moment. I have been searching on the web for about a week now and it was a waist of my time, even Google does not know how to do that. I came out with a very straight forward solution by using Window class and Timer class and it works like a magic.*/
public class View extends VerticalPanel{
private FlexTable flexTable=new FlexTable();
private Button[]buyAndSellButtons = new Button[2];
private TextBox[] textField=new TextBox[2];
private Label alert=new Label();
private LinkedList <String> stock=new LinkedList<>();
public View(){
createComponents();
}
public VerticalPanel createComponents() {
// Assume that the host HTML has elements defined whose
// IDs are "slot1", "slot2". In a real app, you probably would not want
// to hard-code IDs. Instead, you could, for example, search for all
// elements with a particular CSS class and replace them with widgets.
//
HorizontalPanel[] horizontalPanel = new HorizontalPanel[4];
for (int x = 0; x < horizontalPanel.length; x++) {
horizontalPanel[x] = new HorizontalPanel();
}
alert.setStyleName("alert");
add(alert);
flexTable.setText(0, 0, "BUY Orders");
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader");
flexTable.setText(0, 1, "SELL Orders");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader");
flexTable.setStyleName("flexTable");
flexTable.setWidth("33em");
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
add(flexTable);
Label[] labels = new Label[2];
labels[0] = new Label("Volume");
labels[1] = new Label("Price");
for (Label label : labels) {
label.setStyleName("label");
horizontalPanel[1].add(label);
horizontalPanel[1].setStyleName("labelPosition");
}
textField[0] = new TextBox();
textField[0].setTitle("Volume");
textField[1] = new TextBox();
textField[1].setTitle("Price");
for (TextBox textBox : textField) {
textBox.setStyleName("textField");
textBox.setFocus(true);
horizontalPanel[2].add(textBox);
}
buyAndSellButtons[0] = new Button("BUY");
buyAndSellButtons[1] = new Button("SELL");
for (Button button : buyAndSellButtons) {
horizontalPanel[3].add(button);
button.setStyleName("buttons");
horizontalPanel[3].setStyleName("buttonPosition");
}
VerticalPanel[] mainPanel = new VerticalPanel[1];
mainPanel[0] = new VerticalPanel();
for (HorizontalPanel aHorizontalPanel : horizontalPanel) {
mainPanel[0].add(aHorizontalPanel);
mainPanel[0].setStyleName("mainPanel_1");
setStyleName("mainPanel");
add(mainPanel[0]);
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
alert.setText("" + Window.getClientWidth());
}
});
}
Timer timer=new Timer() {
int x;
#Override
public void run() {
alert.setText(Window.getClientWidth()+"Attach" + x++);
String[] gadget=new String[10];
gadget[0]=("354"); //android portrait
gadget[1]=("625");
gadget[2]=("314");
gadget[3]=("474");
gadget[4]=("369");
gadget[5]=("562");
gadget[6]=("617");// android landscape
gadget[7]=("48");
gadget[8]=("730");
alert.setText("" + Window.getClientWidth()+x++);
if(Window.getClientWidth()<=425) {
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader_1");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader_1");
mainPanel[0].setStyleName("phonePortrait_1");
setStyleName("phonePortrait");
flexTable.setStyleName("flexTable_1");
if(Window.getClientWidth()==414){
flexTable.setWidth("26.2em");
}{
flexTable.setWidth("24.2em");
}
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
}
else if((Window.getClientWidth()>425)&&(Window.getClientWidth()<=812)) {
alert.setText("" + Window.getClientWidth());
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader_1");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader_1");
mainPanel[0].setStyleName("phoneLandScape_1");
setStyleName("phoneLandScape");
flexTable.setStyleName("flexTable_1");
flexTable.setWidth("24.2em");
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
}else {
return;
}
}
};
timer.scheduleRepeating(500);
return this;
}
I have a navigation controller with details about a specific product, one of the details is a small image of the product. Now I want to add a button which must go to a view controller with a enlarged image of the product.
How can I make that the enlarged image is on the same navigation controller as the detail screen and as transition an flip of the screen but that the header and tab bar won't flip.
Added a overview image of the two views on the navigation controller.
You can use something like:
UIView.Transition(this.NavigationController.View, 1f,
UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.TransitionFlipFromRight,
delegate { this.NavigationController.PushViewController(this.ImageViewController, false); });
To have your image view flipped in when getting pushed on the navogation controller, instead of the default transition. The title property of the ImageViewController should be the same as the one from your details.
The idea of the UINavigationController is to handle multiple controllers, so you should not work against it by overlaying a view.
Add two views to the controller and animate their frame properties to get the effect you want.
See the example below.
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Drawing;
namespace delete20121203
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow (UIScreen.MainScreen.Bounds);
var ctrl = new MyViewController ();
var nav = new UINavigationController (ctrl);
window.RootViewController = nav;
// make the window visible
window.MakeKeyAndVisible ();
return true;
}
}
public class MyViewController : UIViewController
{
UIButton _button1;
UIButton _button2;
UIView _view1;
UIView _view2;
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
Title = "Test";
_view1 = new UIView (View.Bounds);
_view1.AutoresizingMask = UIViewAutoresizing.All;
_view1.BackgroundColor = UIColor.White;
_button1 = UIButton.FromType (UIButtonType.RoundedRect);
_button1.Frame = new System.Drawing.RectangleF (10, 10, 150, 44);
_button1.SetTitle ("Click", UIControlState.Normal);
_button1.TouchUpInside += Button1Click;
_view2 = new UIView (View.Bounds);
_view2.AutoresizingMask = UIViewAutoresizing.All;
_view2.BackgroundColor = UIColor.LightGray;
RectangleF hideRect = _view2.Frame;
hideRect.X = hideRect.X + hideRect.Width;
_view2.Frame = hideRect;
_button2 = UIButton.FromType (UIButtonType.RoundedRect);
_button2.Frame = new System.Drawing.RectangleF (10, 10, 150, 44);
_button2.SetTitle ("Back", UIControlState.Normal);
_button2.TouchUpInside += Button2Click;
_view1.Add (_button1);
_view2.Add (_button2);
View.Add (_view1);
View.Add (_view2);
}
void Button1Click (object sender, EventArgs e)
{
UIView.Animate (.5f, 0, UIViewAnimationOptions.CurveEaseInOut, delegate {
_view2.Frame = View.Frame;
RectangleF hideRect = _view1.Frame;
hideRect.X = hideRect.X - hideRect.Width;
_view1.Frame = hideRect;
},
null);
}
void Button2Click (object sender, EventArgs e)
{
UIView.Animate (.5f, 0, UIViewAnimationOptions.CurveEaseInOut, delegate {
RectangleF hideRect = _view2.Frame;
hideRect.X = hideRect.X + hideRect.Width;
_view2.Frame = hideRect;
_view1.Frame = View.Frame;
},
null);
}
}
}
I have a menu that displays say
Item1
Item2
Item3
etc. Clicking on Item1 should display me a Table with 2 columns.
I tried something below with displaying just a label. But the label gets displayed somewhere in the screen where as I am expecting it to be a submenu under menuitem1.
JMenu mainMenu = new JMenu("MainMenuHeader");
JMenu menuItem1 = new JMenu(new SomeClassExtendingAbstractAction("menuItem1"));
public class SomeClassExtendingAbstractAction extends AbstractAction {
public SomeClassExtendingAbstractAction(String displayText) {
super(displayText);
}
public void actionPerformed(ActionEvent event) {
try {
SubMenuDialog.showDialog(parent);
} catch (Throwable e) {
}
}
}
public class SubMenuDialog extends JDialog {
public SubMenuDialog(JFrame parent) {
super();
initialize();
}
private void initialize() {
JLabel label = new JLabel();
label.setText("This is test submenu");
getContentPane().add(label);
}
public static void showDialog(JFrame parent) {
SubMenuDialog subMenuDialog = new SubMenuDialog(parent);
subMenuDialog.pack();
subMenuDialog.setVisible(true);
}
}
If I understand correctly, what you want to do is to show arbitrary component in a submenu popup. You obviously cannot use JDialog as it would give you a, you know, JDialog.
Your SubMenuDialog#showDialog can create a JPopupMenu, add any component to it (for example JScrollPane containing a table, or JPanel with labels), and show it where a normal submenu would be.
However it's not a good idea in general to show complicated things in a popup, since it's too easy to lose the popup, plus you may get focus problems with components inside the popup.
I'd suggest you consult a UI designer for the best UI representation of the functionality you want to implement.