How can the background or the color in the navigation bar be changed? - navigationbar

Currently I couldn't find any method to change the color/background of the navigation bar in SwiftUI. Any tips?

In order to change color of navigation bar for all view controllers, you have to set it in AppDelegate.swift file
Add following code to didFinishLaunchingWithOptions function in AppDelegate.swift
var navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.tintColor = uicolorFromHex(0xffffff)
navigationBarAppearace.barTintColor = uicolorFromHex(0x034517)
In here tintColor attribute change the background color of the navigation bar.
barTintColor attribute affect to the color of the:
back indicator image
button titles
button images
Bonus:
Change color of navigation bar title:
// change navigation item title color
navigationBarAppearace.titleTextAttributes =[NSForegroundColorAttributeName:UIColor.whiteColor()]
titleTextAttributes affect to the title text
I hope it helps. :)

In SwiftUI, at this point we can not change it directly, but you can change navigationBar appearance like this,
struct YourView: View {
init() {
UINavigationBar.appearance().backgroundColor = .orange
//Use this if NavigationBarTitle is with Large Font
UINavigationBar.appearance().largeTitleTextAttributes = [.font : UIFont(name: "Georgia-Bold", size: 20)!]
//Use this if NavigationBarTitle is with displayMode = .inline
//UINavigationBar.appearance().titleTextAttributes = [.font : UIFont(name: "Georgia-Bold", size: 20)!]
}
var body: some View {
NavigationView {
Text("Hello World!")
.navigationBarTitle(Text("Dashboard").font(.subheadline), displayMode: .large)
//.navigationBarTitle (Text("Dashboard"), displayMode: .inline)
}
}
}
I hope this will help you. Thanks!!

Till now there is no definitive API in SwiftUI for this purpose. But you can use the appearance API. Here is a sample code.
import SwiftUI
struct ContentView : View {
init() {
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.red]
UINavigationBar.appearance().backgroundColor = .green
}
var body: some View {
NavigationView {
NavigationButton(destination: SecondPage(), label: {
Text("Click")
})
.navigationBarTitle(Text("Title"), displayMode: .inline)
}
}
}

Put a Rectangle behind your NavigationView inside a ZStack:
ZStack {
Rectangle().foregroundColor(.red)
NavigationView {
...
}
}

Please see this answer for a solution that does not use .appearance().
In short use UIViewControllerRepresentable
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
uiViewController.navigationController?.navigationBar...
}

With Introspect you could do it this way:
NavigationView {
Text("Item 2")
.introspectNavigationController { navigationController in
navigationController.navigationBar.backgroundColor = .red
}
}

One thing to note that I didn't at first understand: SwiftUI will change the appearance of things like NavigationBar based on whether you are in night mode.
If you want to default it to a different color scheme add
.colorScheme(.dark)
If you create a color scheme using the color set system as outlined in this post: https://www.freecodecamp.org/news/how-to-build-design-system-with-swiftui/ it would apply to the main elements like navigations and tab bars, and allow you to apply different schemes for night/day mode.

The NavigationView is managing full screens of content. Each of those screens has its own background color. Therefore you can use the following approach to apply your Background color onto the screens:
let backgroundColor = Color(red: 0.8, green: 0.9, blue: 0.9)
extension View {
func applyBackground() -> some View {
ZStack{
backgroundColor
.edgesIgnoringSafeArea(.all)
self
}
}
}
Then you apply it to all your screens:
NavigationView {
PrimaryView()
.applyBackground()
DetailView(title: selectedString)
.applyBackground()
}
Be aware: some SwiftUI views have their own background color which is overriding yours (e.g. Form and List depending on context)

iOS 16
You can set any color to the background color of any toolbar background color (including the navigation bar) for the inline state with a simple native modifier:
Xcode 14 beta 5 (Not working 🤦🏻‍♂️, waiting for beta 6...)
.toolbarBackground(.yellow, for: .navigationBar)
Xcode 14 beta 1,2,3,4
.toolbarBackground(.yellow, in: .navigationBar)
Note that the color will set on the entire bar (up to the top edge of the screen).
Also, the color will be animated during the transition between Large and Inline modes of the bar.

Related

Removing background image from label in tornadofx

I have two css classes on a tornadofx label bound to a SimpleBooleanProperty. One which has a background image and a blue border and one which has no background image and a yellow border.
Snippet from View containing label:
val switch: SimpleBooleanProperty = SimpleBooleanProperty(false)
label("my label"){
toggleClass(UIAppStyle.style1, switch.not())
toggleClass(UIAppStyle.style2, switch)
}
Snippet from UIAppStyle:
s(style1){
textFill = Color.YELLOW
maxWidth = infinity
maxHeight = infinity
alignment = Pos.CENTER
backgroundImage += this::class.java.classLoader.getResource("img.png")!!.toURI()
backgroundPosition += BackgroundPosition.CENTER
backgroundRepeat += Pair(BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT)
borderColor += box(Color.BLUE)
}
s(style2){
textFill = Color.YELLOW
maxWidth = infinity
maxHeight = infinity
alignment = Pos.CENTER
borderColor += box(Color.YELLOW)
}
When switch = false, there is a background image and a blue border. When switch = true, there is the same background image and a yellow border. I'm not finding out how to get the background image to remove. Interestingly enough, if I add a different background image to style2, it changes correctly.
Edit: To remove two toggleClasses and introduce new strange problem:
class MyView : View(){
...
init{
...
row{
repeat(myviewmodel.numSwitches){
val switch = myviewmodel.switches[it]
val notSwitch = switch.not()
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, notSwitch)
}
}
}
}
This code snippet does not work for me. However, if I add private var throwsArray = mutableListOf<ObservableValue<Boolean>>() as a field of MyView and add notSwitch to the array, then the same exact code works. It's almost as if notSwitch is going out of scope and becoming invalidated unless I add it to a local array in the class?
I don’t understand why you want to have two different toggleClass for the same control. As you pointed out, the problem in your case is that when the backgroundImage is set, you need to set a new one in order to change it. But in your case, you only have to add the style without backgroundImage first and them set toggleClass with the style with backgroundImage. Like this:
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, switch)
}
button {
action {
switch.value = !switch.value;
}
}
Edit: This ilustrate what I'm talking about in comments:
class Example : View("Example") {
override val root = vbox {
val switch = SimpleBooleanProperty(false)
val notSwitch = switch.not()
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, notSwitch)
}
button("One") {
action {
switch.value = !switch.value;
}
}
button("Two") {
action {
notSwitch.get()
}
}
}
}
You can put the notSwitch.get() in any action and without trigger that action it does the work. Check how I put it in the action of button Two, but without clicking that button even once, it works.
This is actually some kind of hack, in order to achieve what you want. But I don’t see the reason why my initial solution with true as default value for property shouldn’t work.
Edited to do inverse of status
Here is simple example of a working toggle class using your styling:
class TestView : View() {
override val root = vbox {
val status = SimpleBooleanProperty(false)
label("This is a label") {
addClass(UIAppStyle.base_cell)
val notStatus = SimpleBooleanProperty(!status.value)
status.onChange { notStatus.value = !it } // More consistent than a not() binding for some reason
toggleClass(UIAppStyle.smiling_cell, notStatus)
}
button("Toggle").action { status.value = !status.value }
}
init {
importStylesheet<UIAppStyle>()
}
}
As you can see, the base class is added as the default, while styling with the image is in the toggle class (no not() binding). Like mentioned in other comments, the toggleClass is picky, additive in nature, and quiet in failure so it can sometimes be confusing.
FYI I got to this only by going through your github code and I can say with confidence that the not() binding is what screwed you in regards to the toggleClass behaviour. Everything else causing an error is related to other problems with the code. Feel free to ask in the comments or post another question.

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..

Adding a color box for "Transparent" on the TinyMCE-4 color picker

I'd like an option with the TinyMCE color picker to choose transparent as the color so a character (a "bullet") will still be there and take up space but will not be visible if it's color is transparent.
There's an "X" box option that says "No color" but this seems to make the color black, not transparent.
Does anyone know how to add a transparent color option to this color picker, or even make the "X" box implement transparent instead of black?
Thanks for any ideas.
I believe I was able to do that, I did some quick tests and it appears to be working fine.
I got the latest version of TinyMCE (4.1.10_dev) to access the textcolor plugin's non minified javascript there's this instruction:
if (value == 'transparent') {
resetColor();
} else {
selectColor(value);
}
What happens here? When you choose a color it runs the selectColor, which wraps the selected text in a span with the selected color. However, when you select the no color it removes this color span (that's why it goes back to black which is the default color) instead of setting it to transparent.
So if you do this:
//if (value == 'transparent') {
// resetColor();
//} else {
selectColor(value);
//}
Instead of removing the span it will change it to 'transparent' instead.
One important thing is that tinyMCE gets the plugin scripts automatically, so it only works with the minified versions, so after you do these changes you'll have to minify the script to the plugin.min.js and put it on the textcolro plugin's folder overwriting the one there.
I hope it helps.
The Ă— button in the colorpicker removes any custom colours, it does not add a zero-opacity colour.
As you can see when looking at the source code or trying the full example there is no support for rgba() or opacity in the included colorpicker plugin. Only rgb() and hex unfortunately.
You may need to create your own small plugin to add the ability. There are a number of alternatives, for example:
Create a CSS class which you can add to elements in the editor. Then do your colour magic in your own CSS file.
Create a new button in the toolbar which makes the element transparent.
I would personally go with option two, something like this:
tinymce.init({
selector: 'textarea',
plugins: 'nocolour',
toolbar: 'nocolour',
external_plugins: {
"nocolour": "url_to_your/nocolour.js"
}
});
And nocolour.js:
tinymce.PluginManager.add('nocolour', function(editor, url) {
// Add a button that opens a window
editor.addButton('nocolour', {
text: 'Remove Colour',
icon: false,
onclick: function() {
editor.undoManager.transact(function() {
editor.focus();
// Here is where you add code to remove the colour
editor.nodeChanged();
});
}
});
});
Rafael's solution worked for me. I just wanted to document it a bit more and show what it looks like for TinyMCE 4.1.7.
When you click the "X" in the textcolor grid the "value" variable gets "transparent," rather than a hex value from the colorMap.
The relevant code in the textcolor plugin is:
value = e.target.getAttribute('data-mce-color'); // the hex color from the colorMap square that was clicked. "transparent" if X was clicked
if (value) {
if (this.lastId) {
document.getElementById(this.lastId).setAttribute('aria-selected', false);
}
e.target.setAttribute('aria-selected', true);
this.lastId = e.target.id;
// if (value == 'transparent') { // occurs if you select the "X" square
// removeFormat(buttonCtrl.settings.format);
// buttonCtrl.hidePanel();
// return;
// }
selectColor(value);
The five lines I've commented out remove formatting for the selected text, leaving it black, which doesn't seem useful. If you wanted the text black you could select the black square in the colorMap. Falling through to selectColor(value) with value = "transparent" sets transparent as the color.

customize shape of kendo tooltip

I would like to customize the shape of Kendo Tooltips for a grid.
I saw the example on kendo site, it has the arrow outside the box, and the box has a nice rounded shape.
Working on css, using .k-tooltip I can change width, height, background. But I get a square box with the arrow inside which sometimes overrides part of the text content.
I thought that callout would help but I was not able to get anything.
How can I change shape, image and position of the arrows, shape of the box ?
Moreover, how can I trigger the tooltip only when part of the text in a grid cell is visible ?
Thanks a lot for any hint
regards
Marco
I think "arrow" you mean callout. You can turn off callout by:
$(document).ready(function() {
$("#target").kendoTooltip({
callout: false
});
});
About your question "Moreover, how can I trigger the tooltip only when part of the text in a grid cell is visible?"
If I understand you correctly you would like to show tooltip only when there is text with ellipsis (partially visible in the cell), but you don't want to show a tooltip if there is a full text is visible or if there is no text in the cell. If that is the case, you can do this way:
function initializeTooltip(element, filter) {
return element.kendoTooltip({
autoHide: true,
filter: filter,
callout: false,
content: function (e) {
var target = e.target,
tooltip = e.sender,
tooltipText = "";
if (isEllipsisActive(target[0])) {
tooltipText = $(target).text();
}
tooltip.popup.unbind("open");
tooltip.popup.bind("open", function (arg) {
tooltip.refreshTooltip = false;
if (!isEllipsisActive(target[0])) {
arg.preventDefault();
} else if (tooltipText !== $(target).text()) {
tooltip.refreshTooltip = true;
}
});
return tooltipText;
},
show: function () {
if (this.refreshTooltip) {
this.refresh();
}
}
}).data("kendoTooltip");
};
// determanes if text has ellipsis
function isEllipsisActive(e) {
return e.offsetWidth < e.scrollWidth;
}
$(function () {
initializeTooltip($("#yourGridId"), ".tooltip");
});
tooltip in this case is class name of the column that you would like to use tooltip for, but you can call that class anyway you wish. In case if you are using Kendo ASP.NET MVC it will look something like this
c.Bound(p => p.ClientName)
.Title("Client")
.HtmlAttributes(new {#class = "tooltip"});

How can I change the size of icons in the Tree control in Flex?

I embed SVG graphics in my Flex application using
package MyUI
{
public class Assets
{
[Embed(source="/assets/pic.svg"]
[Bindable]
public static var svgPic:Class;
}
}
and then extending the Tree class with some of my own code, setting the icon upon adding a node to the data provider:
public class MyTree extends Tree
{
public function MyTree()
{
// ...
this.iconField = "svgIcon";
// ...
this.dataProvider = new ArrayCollection;
this.dataProvider.addItem({ /* ... */ svgIcon: MyUI.Assets.svgPic /* ... */ });
// ...
}
}
Now I have two things I want to do:
use the SVG graphics in multiple places in the app, scaling them to the appropriate size for each appearance, i. e. scale them to a proper icon size when using them in the tree
change the size of the icon at runtime, e. g. display a slightly larger icon for selected items or let an icon "pulse" as a response to some event
I read the Flex documentation on the 9-slice scaling properties in the Embed tag, but I think that's not what I want.
Edit:
I unsuccessfully checked the "similar questions" suggested by SO, among others this one:
Flex: Modify an embedded icon and use it in a button?
Subclass mx.controls.treeClasses.TreeItemRenderer and make it resize the icon to your desired dimensions, or create your own item renderer implementation by using the same interfaces as TreeItemRenderer. Set a custom item renderer with the itemRenderer property:
exampleTree.itemRenderer = new ClassFactory( ExampleCustomItemRendererClass );
The answer to this question might point you in the right direction, without knowing more about the trouble you're having:
Flex: Modify an embedded icon and use it in a button?
Hope it helps!

Resources