SwiftUI TabView NavigationSplitView - swiftui-navigationsplitview

I have a TabView with four tabitems which destinations are four NavigationSplitView. The Sidebar button is repeating for the four NavigationSplitViews on macOS like on below display. On iPad it works properly. How to fix the Sidebar button to display only one related to the NavigationSplitView selected in the TabView. Xcode 14.2, MacOS 13.2. Thanks
enter image description here
struct ContentView: View {
var body: some View {
TabView() {
Tab1View().tabItem { Label("Tab1", systemImage: "star")}
Tab2View().tabItem { Label("Tab2", systemImage: "star")}
Tab3View().tabItem { Label("Tab3", systemImage: "star")}
Tab4View().tabItem { Label("Tab4", systemImage: "star")}
}
}
}
struct Tab1View: View {
var body: some View {
NavigationSplitView {
Text("Tab1")
}detail: {
Text("Detail Tab1")
}
.navigationSplitViewStyle(.automatic)
}
# Tab2View, Tab3View, Tab4View like Tab1View

Related

How to unmute colors in SwiftUI's NavigationSplitView sidebar

I am using NavigationSplitView, introduced in iOS16, with a basic list and attempting to color a system image with standard colors. I am noticing that when the navigationSplitViewStyle is .automatic or .prominentDetail and the color scheme is dark, that the colors are muted. I have not been able to figure out how to not-mute them, and thus stick with the original color as it's used in light mode. I'm wondering if this is possible to override? Or is there a way to drop down to UIKit and override this odd behavior?
Here is an example:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationSplitView {
List {
ForEach([1, 2, 3], id: \.self) { item in
Button {
} label: {
HStack {
Image(systemName: "sunset.circle.fill")
.foregroundColor(.green)
Text("Item \(item)")
}
.font(.system(size: 40))
.padding()
}
}
}
} detail: {
Text("Detailed Content")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
.previewInterfaceOrientation(.portrait)
.preferredColorScheme(.dark)
ContentView()
.previewInterfaceOrientation(.portrait)
.preferredColorScheme(.light)
}
}
}
And you can see the different in the color between schemes here:
If you meant that in dark mode, the sun in the symbol is black and you want to keep it white, then you can achieve this by setting symbolRenderingMode modifier on the image to .palette and give it two colors, the green one as well as white using the foregroundStyle modifier.
Image(systemName: "sunset.circle.fill")
.symbolRenderingMode(.palette)
.foregroundStyle(.white, .green)
Refer to the following session from WWDC 2021 for more about using rendering modes for SF Symbols in SwiftUI: https://developer.apple.com/wwdc21/10349
If you want the colors to be exactly the same and don’t change. You can use UIKit’s colors or define your own custom colors that don’t support dark mode.
.foregroundStyle(.white, Color(uiColor: .green))
.foregroundStyle(.white, Color(red: 0, green: 1, blue: 0))
See the Fixed Colors section in this link:
https://developer.apple.com/documentation/uikit/uicolor/standard_colors

Scroll to bottom of a list populated with CoreData in SwiftUI

I'm trying to scroll to the bottom of List when a button is tapped. I have tried placing the List in a ScrollViewReader and this seems to work only when the List is populated using an array. When I populate the List using CoreData's FetchedResults the List doesn't scroll for some reason.
var array = Array(0...100)
private var items: FetchedResults<Item>
NavigationView {
ScrollViewReader { (proxy: ScrollViewProxy) in
List{
ForEach(items) {item in
Text(item.text!)
}
}
Button("Tap to scroll") {
proxy.scrollTo(10, anchor: .top)
}
}
}
Here if i use items it doesn't scroll but when I replace items with array the list scrolls as expected.
scrollTo() works by receiving an identifier, not an index.
Using array works because 10 is contained in array, but 10 cannot match item.
I would suggest you add an ID String property to your objects (I think you could even use object.uriRepresentation()) tag your views with that identifier, and now you'll be able to use scrollTo.
private var items: FetchedResults<Item>
NavigationView {
ScrollViewReader { (proxy: ScrollViewProxy) in
List{
ForEach(items) {item in
Text(item.text!)
.id(item.id)
}
}
Button("Tap to scroll") {
proxy.scrollTo(items[10].id, anchor: .top)
}
}
}
}

SwiftUI Checkbox Is Not Displaying The Check Mark When Clicked

I generate a dynamic checkbox list
struct DemoStatusSearchView: View {
#ObservedObject var myObject = myObject ()
var body: some View {
VStack(alignment:.leading, spacing:20) {
Text("My Check Box List")
.font(.system(size: 16))
.bold()
.foregroundColor(.black)
ForEach(myObject.checkBoxList, id:\.id) { item in
CheckboxField(
id: item.checkboxDesc ,
label: item.checkboxDesc ,
callback: self.checkboxSelected
)
}
}.padding(20)
}
But when I click on the checkbox, the checkmark is not displayed.
I looked into my code that the view is being refreshed multiple times based on the multiple calls from the view model class. I clearly don't have an idea how the object state is working in the Combine and SwiftUI, this is the root caused of this issue.
Thank you #pawello2222 for posting me to the right direction.

React Dnd useDrag is not working properly?

I'm using react dnd and it's useDrag method not working properly. Let me elaborate the situation:
User will drag list item from left to right as stated below:
Final outcome of right side will be like this below pic,
every list items list 1, 2, 3 will be draggable everywhere and droppable.
The list items List 1 useDrag code is :
const [{ isDragging }, drag, preview] = useDrag({
item: {
type: 'tool',
id: id
},
canDrag: true,
begin(props, monitor, component) {
document.querySelectorAll(".rowWrapper").forEach(function(item){
item.classList.add("rowBorder", "pd-row-drag", "mb-row-drag");
});
document.querySelectorAll(".drop-area").forEach(function(element) {
element.classList.add("dropAreaPosition");
});
document.querySelectorAll(".rowBorderOverlay").forEach(function(element) {
element.classList.add("hideElement");
});
document.querySelectorAll(".rowActions").forEach(function(element) {
element.classList.add("hideElement");
});
},
end(props, monitor, component) {
document.querySelectorAll(".rowWrapper").forEach(function(element) {
element.classList.remove("rowBorder", "pd-row-drag", "mb-row-drag");
});
document.querySelectorAll(".dropZone").forEach(function(element) {
element.classList.remove("showDropZone");
});
document.querySelectorAll(".drop-area").forEach(function(element) {
element.classList.remove("placeHolder","dropAreaPosition");
});
document.querySelectorAll(".rowActions").forEach(function(element) {
element.classList.remove("hideElement");
});
},
collect: monitor => ({
item: monitor.getItem(),
isDragging: !!monitor.isDragging()
}),
});
What I'm doing here is, when dragging begins I'm doing the above stuff like adding classes/removing. By doing like this, useDrag is not working properly when you drag list 1 the full container is not draggable only the portion of it.
if I remove begin, end I can drag the entire container, I don't know what's causing the problem here ?
Any help on this really appreciable ? or how do I do the stuff like adding classes/removing whild dragging or drag begin ?

ext js 4 reuse grid in MVC, rows dissapear

I have a problem in my ext JS applicatiom. Use MVC architecture:
Ext.define('ME.controller.Stocks', {
extend:'Ext.app.Controller',
models:[
'Logs'
],
stores:[
'Logs'
],
views:[
'portal.portalItems.logGridPanel.LogGridPanel',
'portal.portalItems.logGridPanel.LogGrid',
'portal.PortalPanel',
'portal.PortalDropZone',
'portal.PortalColumn',
'portal.Portlet',
'portal.portalItems.base.Panel',
]
});
Component with name 'LogGrid' adds to viewport dynamically. Its initcomponent function looks like:
initComponent: function()
{
var me=this;
var store= Ext.create('ME.store.Logs', {
storeId:Utils.formUID(LOGS_GRID.LOGS_STORE_ID, me[FIELDS_MAPPER.BASE_PANEL.CLIENTSIDE_GUID]),
sorters:[
{
property:FIELDS_MAPPER.LOGS_GRID.LOG_DATE,
direction:'DESC'
}
]
});
this.store=store;
this.columns=[
{
text:Message.get('console.portal.logGrid.DateHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.LOG_DATE,
renderer:Ext.util.Format.dateRenderer('H:i:s<br>d.m.Y')
},
{
text:Message.get('console.portal.logGrid.DepartmentHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.DEPARTMENT_NAME
},
{
text:Message.get('console.portal.logGrid.ProtectionSystemsHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.PROTECTION_SYSTEM_NAME
},
{
text:Message.get('console.portal.logGrid.PlanHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.PLAN_NAME
},
{
text:Message.get('console.portal.logGrid.SourceHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.SECTION_NAME
},
{
text:Message.get('console.portal.logGrid.MessageTextHeaderText'),
dataIndex:FIELDS_MAPPER.LOGS_MODEL.EVENT_TYPE_NAME,
minWidth:200
},
{
dataIndex:FIELDS_MAPPER.LOGS_MODEL.EVENT_STATE_NAME,
text:Message.get('console.portal.logGrid.StateHeaderText')
// renderer:changeStateColor
}
];
me.callParent(arguments);
}
Logs store is:
Ext.define('ME.store.Logs', {
extend:'Ext.data.Store',
model:'ME.model.Logs',
proxy:{
type:'ajax',
url:URLS.JOURNAL_CONTROLLER,
extraParams:{action:'getEvents'},
actionMethods:{
read:'POST'
},
reader:{
type:'json',
idProperty:FIELDS_MAPPER.LOGS_GRID.LOG_ID
},
autoLoad:false
},
pageSize:LOGS_GRID.ITEMS_PER_PAGE
});
PROBLEM IS:
When I have one instance of grid, everything OK, but when I add new instance of grid, rows (selection model) dissapears from both grids. Such bug appears also when I collapse grids.
If it will be useful, grid component is situated in different panels.
And also I saw such thing:
When I create LogsGrid in one container with grid that uses different store, such bug appears too, but now rows from logGrid moves to another grid.. I don't know what to do.. Second day can't find an answer

Resources