TitleView of UITableViewController's UINavigationItem image not visible - uinavigationcontroller

I am using Swift 2.3 in Xcode 7.3. I have a UINavigationController with a UITableViewController. I am trying to set the titleView of the navigation item in the navigationBar to create a button centered in the navigation bar.
The indexTextBut is a UIButton hooked up from the story board. I have tried just creating a new button and it made no perceivable difference. The way I am currently doing it the button is there as it has the behavior it should but no image. I have tried just setting the title field as a string and even then I see nothing. I set the right and left barButtonItems using:
navItem.setRightBarButtonItems(barButtonItems, animated: false)
navItemArray.append(navItemCatDet)
self.navigationController?.navigationBar.setItems(navItemArray, animated: false)
Here is my relevant code. My big question is why can't I see the image of the button being set to the titleView. It has preset behavior and when I click where it should be I get that behavior. I've tried adjusting the frame of the UIButton and its UIImageView, and the size of the UIImageView's image but have had no luck. I included the line aobut tinting the background just incase it is related even though I have tried it with and without.
class MyTableViewController: UITableViewController, UITextFieldDelegate {
#IBOutlet weak var indexTextBut: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
var indexNavItemArray = [UINavigationItem]()
var indexNavItem = UINavigationItem()
indexNavItem.titleView = newButton
indexNavItemArray.append(indexNavItem)
self.navigationController?.navigationBar.barTintColor = UIColor(netHex:0xe63246)
self.navigationController?.navigationBar.setItems(indexNavItemArray, animated: false)

swift 3.0
var indexNavItemArray = [UINavigationItem]()
var indexNavItem = UINavigationItem()
indexNavItem.titleView = indexTextBut
indexTextBut.setTitle("button", for: .normal)
indexNavItemArray.append(indexNavItem)
self.navigationController?.navigationBar.barTintColor = UIColor.lightGray
self.navigationController?.navigationBar.setItems(indexNavItemArray, animated: false)
replace your code to above.

Related

UIBarButtonItem not change image automatically when switching dark mode/light mode

I am trying to integrate dark mode support to my app. But when setting image icon for UIBarButtonItem, it seem only works when the first time UIBarButtonItem is shown, it is not changed when I switch between dark mode/light mode.
When using that image with other UIButton, it works fine.
So I wonder if I am missing something?
P/s: I have to use that trick for updating image:
let item: UIBarButtonItem = UIBarButtonItem()
let button: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 26, height: 19))
button.setImage(UIImage(named: "hamburger"), for: .normal)
button.addTarget(self, action: action, for: .touchUpInside)
item.customView = button
Seems to be a bug in iOS, but one way around this is, to use traitCollection delegate method to set the correct image manually.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
let imageAsset = UIImage(named: "YOUR_IMAGE_NAME")?.imageAsset
let resolvedImage = imageAsset?.image(with: traitCollection)
self.YOUR_BUTTON.image = resolvedImage
}

Changing cursor on a bokeh map

I've made a map using Bokeh, like the first example on this page, except the user can zoom in/out by scrolling up/down, and can tap circles I've added to the map to select them.
At the moment when the cursor is over the map it's the default arrow. If I click and drag the map the cursor changes to the text cursor for some reason. It doesn't change with any other action.
I'd like to be able to change the cursor appearance so that:
When over the map it's the grab cursor
When dragging the map it's the grabbing cursor
When over a circle it's the pointer cursor
I can achieve (1) with:
.bk { cursor: grab; }
but I'm not sure how to achieve the other two.
Following suggestions from the other post I came with this: (works for Bokeh v1.3.0):
from bokeh.models import CustomJS, HoverTool
from bokeh.plotting import figure, show
p = figure(tools='pan, tap, reset')
p.circle(x=[1,2,3], y=[1,2,3], size=30)
code_pan_start = '''
Bokeh.grabbing = true
var elm = document.getElementsByClassName('bk-canvas-events')[0]
elm.style.cursor = 'grabbing'
'''
code_pan_end = '''
if(Bokeh.grabbing) {
Bokeh.grabbing = false
var elm = document.getElementsByClassName('bk-canvas-events')[0]
elm.style.cursor = 'grab'
}
'''
code_hover = '''
if((Bokeh.grabbing == 'undefined') || !Bokeh.grabbing) {
var elm = document.getElementsByClassName('bk-canvas-events')[0]
if (cb_data.index.indices.length > 0)
elm.style.cursor = 'pointer'
else
elm.style.cursor = 'grab'
}
'''
p.js_on_event('panstart', CustomJS(code = code_pan_start))
p.js_on_event('panend', CustomJS(code = code_pan_end))
p.add_tools(HoverTool(callback = CustomJS(code = code_hover)))
show(p)
You could potentially use the PanStart and PanEnd events to set/reset the cursor on drag operations. I think the hover will be difficult to achieve. Currently there is a callback property on hover tools that can be used trigger JS code when an inspection happens on a point. But it only fires when there is an inspection, there is no corresponding event or hook for "un-inspection" so I am not sure how you would reliably clear the cursor state when the user is no longer hovering over the circle.

I want my buttons and BG to stay in one position as the view controller elements transition

I have been working on this for hours(today)/months. I just want my BG to stay permanent in all view controllers as well as the same buttons with the same commands for all of them.
It is only the foreground element that is transitioning around in the center of the viewfinder, from side to side.
I tried using a subclass, it did not effect my view controller at all. When it came to trying to get my buttons to stay, i tried to cheat and use a tab bar, but the tab bar controller is locked at the bottom and I can't move it up the y axis.
Is there an easier way? Is there a way to make a view controller have the main components and every other view controller has sub components that transitions, one from another using the main components controller.
When attempting to make a subclass, I made a touch class file and put..
import UIKit
class WallpaperWindow: UIWindow {
var wallpaper: UIImage? = UIImage(named: "BG.png") {
didSet {
// refresh if the image changed
setNeedsDisplay()
}
}
init() {
super.init(frame: UIScreen.main.bounds)
//clear the background color of all table views, so we can see the background
UITableView.appearance().backgroundColor = UIColor.clear
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func draw(_ rect: CGRect) {
// draw the wallper if set, otherwise default behaviour
if let wallpaper = wallpaper {
wallpaper.draw(in: self.bounds);
} else {
super.draw(rect)
}
}
and then put
var window: UIWindow? = WallpaperWindow()
into my AppDelegate...
the code was working find, just my background did not change at all...
Related in making the tab bar move up the y axis I had no luck, it was locked....counting even tough the UIcoding..

How do I scroll an Editor that has been obscured by the keyboard into view?

I'm designing a UI in Xamarin.Forms to collect feedback from users about our application. There is an Editor control at the bottom of this page. On an iPhone 4S, and in many landscape orientations, the keyboard completely obscures this editor control. On Android, this is not a big deal because the OS automatically scrolls (though the sizing behavior is a little weird.) On iOS, the only things resembling solutions are very wonky.
In native iOS, the solution is simple: wrap your views in a UIScrollView, then when the keyboard appears add that much space to the content size and scroll appropriately. Xamarin doesn't expose anything to control the scroll position in ScrollView, and ContentSize is private, so that's out. A few posts (here and here) seem to indicate ScrollView is at least part of the solution. It does appear Xamarin has some automatic scrolling behavior, but it's... curious.
My layout is fairly simple:
At the top, a fixed navigation bar that I do not want to scroll out of view.
Beneath that, a 180px tall image that represents a screenshot of the application.
Beneath that, a label with information such as the timestamp. (2-3 lines of text).
Beneath that, the editor, filling the remaining available space.
I've included code for a layout I've tried at the bottom of my post. I created a StackLayout that contains the image, the label, and the editor. I put that inside a ScrollView. Then, I create a RelativeLayout and place the navigation bar at the top-left with the ScrollView beneath it.
What I want to happen when the Editor is tapped is for the keyboard to be displayed and, if it obscures the Editor, for the layout to be nudged upwards to make the Editor visible. What happens instead is it seems like Xamarin scrolls the layout upwards by the keyboard height plus some margin that looks suspiciously like the keyboard utility bar height. This shoves the Editor upwards so high it's obscured by the navigation bar.
I've tried a lot of different tweaks and I'm at a loss. I can't control enough of the ScrollView to get the behavior I need. I've seen suggestions that use a BoxView resized when the Editor gains focus, but to make it work really well I'd still have to hook into the iOS notifications to get the appropriate size and have a fairly intimate knowledge of where my Editor's bounds are. It feels wrong.
Does anyone else have a solution to this on Xamarin.Forms? Even if I have to dip into native, I'd like an answer.
(Here's an example layout that demonstrates the problem, there's a little bit of weird structure because I was debugging. The funky colors are also a relic of layout debugging.)
using System;
using Xamarin.Forms;
namespace TestScroll
{
public class MainPage : ContentPage {
public MainPage() {
InitializeComponent();
}
private ScrollView _scroller;
protected void InitializeComponent() {
var mainLayout = new RelativeLayout();
var navbar = new Label() {
BackgroundColor = Color.Blue,
TextColor = Color.White,
Text = "I am the Nav Bar",
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.StartAndExpand
};
var subLayout = new ScrollView() {
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand
};
_scroller = subLayout;
var subStack = new StackLayout();
subStack.Spacing = 0;
subLayout.Content = subStack;
var image = new BoxView() {
Color = Color.Green,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Fill,
HeightRequest = 300
};
subStack.Children.Add(image);
var infoLabel = new Label() {
BackgroundColor = Color.Blue,
TextColor = Color.Black,
Text = "Timestamp!\r\nOther stuff!",
VerticalOptions = LayoutOptions.Start
};
subStack.Children.Add(infoLabel);
var editor = new Editor() {
VerticalOptions = LayoutOptions.FillAndExpand
};
subStack.Children.Add(editor);
mainLayout.Children.Add(navbar,
Constraint.Constant(0),
Constraint.Constant(20),
Constraint.RelativeToParent((parent) => parent.Width),
Constraint.Constant(70));
mainLayout.Children.Add(subLayout,
Constraint.Constant(0),
Constraint.RelativeToView(navbar, (parent, view) => navbar.Bounds.Bottom),
Constraint.RelativeToParent((parent) => parent.Width),
Constraint.RelativeToView(navbar, TestConstraint));
Content = mainLayout;
}
private double TestConstraint(RelativeLayout parent, View view) {
double result = parent.Height - view.Bounds.Height;
Console.WriteLine ("Lower stack height : {0}", result);
Console.WriteLine ("Scroll content size: {0}", _scroller.ContentSize);
return result;
}
}
}
One thing I notice is that you are adding a ScrollView (subLayout) to another ScrollView (_scroller).
Also, I ran into this same problem on iOS except all of my controls were within a Grid. Simply putting the Grid into a single ScrollView fixed the problem, without having to change content sizes or anything like that.
This question sat for a long time unanswered, here's what I did. I don't know that it's the 'answer', and I do appreciate hvaughan3's answer that's currently here and I will try it if I ever get the time.
My page behaved like I wanted on Android, so I didn't do anything specific for that.
So I wrote specific code for iOS that used the notifications UIKeyboardWillShow and UIKeyboardWillHide. These notifications provide information about the bounds the keyboard will take up. So when I get a 'show' notification, I manipulate my layout to allow room for an element of that size I place underneath the keyboard. When I get a 'hide' notification, I reset the layout.
It's janky and a little embarrassing, I hope to come back with news I tried another solution like hvaughan3's and it worked.

iOS 8 Bug with UIImagePickerController Image Crop

I am having an issue with UIImagePickerController with allowsEditing = YES.
I am unable to crop the image from the bottom but also I have an extra empty space on top when moving the crop rectangle.
Also in the method.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
I log info and it gives me wrong CropRect (which is not square!)
UIImagePickerControllerCropRect = "NSRect: {{0, 357}, {666, 646}}";
UIImagePickerControllerEditedImage = "<UIImage: 0x7f9b8aa47b30> size {640, 618} orientation 0 scale 1.000000";
UIImagePickerControllerMediaType = "public.image";
UIImagePickerControllerOriginalImage = "<UIImage: 0x7f9b8868e5a0> size {1500, 1001} orientation 0 scale 1.000000";
Does anyone has this bug and how do you fix it?
See the picture below
I have no idea how, but i totally removed "View controller-based status bar appearance" key row (just fully delete this row) in .plist file and it fixed this bug
I couldn't set the "View controller-based status bar appearance" to YES, so I have tried to hide the status bar when I show the UIImagePickerController like so:
let imagePickerController = UIImagePickerController()
...
myViewController.present(imagePickerController, animated: true) {
UIView.animate(withDuration: 0.25, animations: {
UIApplication.shared.isStatusBarHidden = true
})
}
Then on the UIImagePickerControllerDelegate didFinishPickingMediaWithInfo I show the status bar, and it worked.

Resources