I have an interesting challenge, but I do not know where to start.
given an NSTextView in an NSScrollView, and enough text in the textView to enable scrolling, how do you determine the location of a single word, and jump to it?
we see this sort of behavior in Find panels in Most text editors. So it can be done.
additionally, I would very much like to find some kind of predetermined... elements in the text. as a link or an image is not text but can be inline with the text (in Attributed strings) I would like to put an element in the text that is not text, but is targetable and capable of being tagged with some kind of reference. Almost like a bookmark, in which I can scroll to. I have determined that I could use URL Links. But they are so fragile.
Post
Replies
Boosts
Views
Activity
I have a Mac doc based app.
I have save methods setup (they sort of work... I'm trying to get them up and running)
I'm using NSSecureCoding, with NSObjects in Swift. It has been unusually frustrating.
I have run into something I find wildly difficult to even explain.
I can save a new document that has not been saved yet. it loads as expected.
but if I make a change to a doc I have already saved, and save that, ny file gets wiped out. my save code is called, and the app wipes all of the data out of the saved file. The file exists, but it's emptied.
it goes from around ~200k in size to 2k in size.
there's no error that I have identified. It just wipes my file. So I have NO idea if it's something I did.
docs are... unhelpful. internet searches... are unhelpful.
this is just one of a number of errors I have to figure out, but it is massively complicating everything else.
any ideas welcome.
I have a doc, xib based project.
it has an NSCollectionView, which properly displays the data. including items and section headers.
I have drag n drop enabled where I can drop into the collectionView, and I generate a new object. this is NOT a reordering issue (yet)
when I drop into the collectionView, if the drop is on top of a HeaderView, the drop is canceled (before it gets to my delegate code.) But more importantly : the Header views are entirely ignored in every step of the drag and drop. the hinting, only ever shows up adjacent to a collectionViewItemView, Never below or above the section header. The drop ALWAYS has a section of zero in its index path. regardless of where the drop is.
I tried to override this behavior in both the validate drop and accept drop methods. with a great deal of frustration and struggle I discovered that I cannot compare the placement of my header views, because the frames of those views are all at the base origin point.
is this normal behavior? Has anyone else run into this? is there a fix?
Hi, caught in a loop of unhelpful error messages. Been trying to find a code example to follow, apparently that is not a thing anymore. the docs... for over 20 years now are only half finished. So Im here in the forums looking for guidance.
I am trying to set a resource for an existing file URL. the intention is to add a tag to the file. Nothing onerous. Should be easy. Getting the list of tags WAS easy.
here's the code as I have it:
func setItemTags(atURL:URL, tags: [String]){
do {
try atURL.setResourceValue(tags, forKey: .tagNamesKey)
} catch let error as NSError {
print(error)
}
}
I get an error that says:
Argument type '[String]' expected to be an instance of a class or class-constrained type
ok. seems pretty straight forward, the Array (which is what I get from acquiring the resources... so this doesn't make much sense at all, but whatever.) needs to be a class. clearly it's a Holdover from Obj-c. And it needs to be an NSArray. I SHOULD be able to bridge to an NSArray by replacing 'tags' with 'NSArray(array: tags)'
but that doesn't work at all. I get a different error.
'setResourceValue(:forKey:)' is unavailable: Use struct URLResourceValues and URL.setResourceValues(:) instead
So no error message is really telling us anything. no matter how much I try, I can't just materialize the answer out of thin air.
what I really need is a single example of how to properly use the 'steresourceValue' function of URL, to set the .tagNamesKey. I am astonished that this is not documented anywhere.*
*I have found ancient examples of this, which is now deprecated by changes to swift, and is only useful as a source of confusion.
I have hit a brick wall. I cannot explain the behavior I am seeing. What it boils down to is: SIMD2<Float> is incompatible with float2.
I am working through tutorials trying to get a handle on Metal. All the tutorials are woefully out of date, so no answers there. But I did find somewhere that I should be using SIMD4<Float> for my point data. Great. I was able to bridge that gap. but I added uv maps using a float2. and the result was a portion of my vertex data gets lost somewhere. The buffer is smaller, by about 25%.
and I cannot figure it out. help?
in anticipation of pertinent questions:
the vertex struct:
struct vertex {
var position : SIMD4<Float> = SIMD4<Float>(x: 0.0,y: 0.0,z: 0.0,w: 0.0)
var uv : SIMD2<Float> = SIMD2<Float>(x:0.0 ,y:0.0)
init(x: Float ,y: Float, z: Float) {
self.position.x = x
self.position.y = y
self.position.z = z
self.position.w = 1.0
uv = SIMD2<Float>(0.5 ,0.5)
}
init( x: Float, y: Float, z: Float, u: Float, v: Float ){
position = SIMD4<Float>(x,y,z,1.0)
uv = SIMD2<Float>(u ,v)
}
}
if I change the SIMD2 to an SIMD4... the entire thing works.
how I measure the size of my buffer:
let matrixSize = MemoryLayout.size(ofValue:vertexField.vertices[0])
let vertsSize = vertexField.vertices.count * matrixSize
// now we make the vertex buffers.
for i in 0..<maxFramesInFlight{
if let aVertBuff = device.makeBuffer(bytes: vertexField.vertices, length: vertsSize, options: .storageModeManaged){
aVertBuff.label = "verts buffer \(i)"
vertexBuffs += [aVertBuff]
}
}
vertexField is a struct containing an array of vertices, and an array of offsets and lengths for the various meshes I make from those vertices. Eventually I'll figure out the elegant way of doing that.
the buffer winds up having 64 elements, out of 84. The fragment shader, assumes 84 entries, and winds up setting those values to 0,0,0,0 0,0.
I sent a single SIMD2<Float> variable to the Fragment shader, and examined it. It was correct.
any ideas are welcome. I am up the river without a paddle on this one.
new to Metal,
following Janie Clayton's book. Ran into a problem creating a proper Perspective Projection Matrix.
I'm hoping someone with matrix experience will see this and the issue will jump out.
the matrix structures:
swift:
struct Matrix4x4{
var X : SIMD4<Float>
var Y : SIMD4<Float>
var Z : SIMD4<Float>
var W : SIMD4<Float>
metal:
float4x4 projectionMatrix;
the swift code that generates the projection matrix:
static func perspectiveProjection(_ aspect : Float32, fieldOfView: Float32, near: Float32, far: Float32)->Matrix4x4{
var mat = Matrix4x4()
let zRange = far - near
let fovRadians = fieldOfView * Float32(Double.pi / 180.0)
let yScale = 1 / tan(fovRadians * 0.5)
let xScale = yScale / aspect
let zScale = -( far + near) / zRange
let wzScale = -2 * far * near / zRange
mat.X.x = xScale
mat.Y.y = yScale
mat.Z.z = zScale
mat.Z.w = -1
mat.W.z = wzScale
mat.W.w = 0
return mat
}
how the shader applies the projection matrix :
outVertex.position = uniforms.projectionMatrix * props.modelMatrix * vert[vid].position;
the result here is just the clear color.
it seems that the issue is with wZScale. hard coding that to zero and the mat.W.w to 1.0, allows me to at least see my scene, skewed. messing around with those values, it seems like the objects are crushed and pushed through the camera, existing behind it.
I'm basically dead in the water here, typing word for word what is in the book. it's pretty darned frustrating. I'm just learning my way around matrices.
using this:
https://developer.apple.com/documentation/metal/modern_rendering_with_metal
I have tried downloading and building several times. Ever since I installed the W5700X the project builds, runs, and only loads the lights, but not the model.
what gives? There's no bugs, it just doesn't load the "bistro" file.
I have a plugin architecture... the plugins are glorified bundles.
They are compiled at runtime, and embedded in the Main Application Bundle's Plugin folder.
I have hit the point where I need to load the plugins, and query them for data, from inside one of the plugins.
this is usually accomplished in the main bundle with a class :
import Foundation
import CNPlugin
class CNPluginMan{
var plugins : [CNPlugin] = []
init() {
loadPlugins()
}
func loadPlugins(){
do {
let files = try FileManager.default.contentsOfDirectory(at: Bundle.main.builtInPlugInsURL!, includingPropertiesForKeys: nil)
for URL in files{
let aBundle = Bundle(url: URL)
if let als = aBundle?.principalClass{
if let cls = als as? CNPlugin.Type{
let plugin = cls.init()
plugins.append(plugin)
}
}
}
} catch {
print(error)
}
}
}
but Now I am acutely aware that I can't just get the main bundle.
is there a correct way, to get the Host Application's Bundle from a plugin?
I have a number of objects that handle Drops, all of their code is descended from a single object where I noticed an oddity in Drag n drop behavior. That that is, if I do not add a particular set of lines to the performDrop method, the pasteboard appears to be empty.
what gives?
open override func performDragOperation(_ sender: NSDraggingInfo, forCon: BKLayerController) -> Bool{
var retVal = false
let paneRec = forCon.rep as! CNPanelRecord
		 let pasteBoard : NSPasteboard = sender.draggingPasteboard
		if pasteBoard.types?.contains(CNDragTypeToolBox) == true{
					 retVal = true
					 let encoder = JSONEncoder()
					 let thePoint = CGPoint()
/* if I do not add this if statement... drag n drop does not work */
					 if let newPlistData = pasteBoard.propertyList(forType: CNDragTypeToolBox){}
		let payload = pasteBoard.readObjects(forClasses: [pBoardNode.self], options: nil)
					let droppedItems : [CNDagObj] = (payload as! [pBoardNode]).map({$0.docNode.dagObjs}).flatMap { $0 }
					for each in droppedItems{
							each.uuid = UUID().uuidString
											do {
	 let ptData = try encoder.encode(thePoint)
	 if let env = paneRec.focus as? CNEnvelopment{
															 env.dagObjPos[each.uuid] = ptData
													 }
} catch {
debugPrint("tring to convert a Point to a Data, in updateLayout in CDEditorDel")
}
}
if var env = paneRec.focus as? CNEnvelopment{
env.dagObjs += droppedItems
}
}
return retVal
}
forgive formatting and code issues. it works just fine, but I had a heck of a time fixing the formatting in the Forum editor. There's likely now, a LOT of text that used to be comments... how could that be any worse? Anyway, "if let newPlistData = pasteBoard.propertyList(forType: CNDragTypeToolBox){}" is the line. if that is not called, the drop pasteboard is empty, if it is called, my objects are there.
I don't need that object, it has nothing at all to do with anything I am doing. Why is it necessary?
also: @Apple... you really messed up the forums. this is so difficult to work with.
I have long since gone through converting my classes to support Codable, And I had an issue where I was using one of the powerful features of Objective programming, inheritance, to make an Array of a generic class, and populate it with subclasses of that class.
You can't just decode that array with the generic class type, you have to tear apart the array into separate arrays of the various subclass types, archive them and when you decode them, merge them back into that single array.
I get 'why' Codable forces you to name the type before you decode the object. security. makes sense. I'm 100% on board.
but I need to be able to duplicate the effect of having a Generically typed array, with subclasses in it, that can be saved to disk.
originally, I created an intermediate class that did tear apart the array, and then put it back together. The main issue with this is: it is impossible to make it portable. You'd have to write an entire class per array type. Further, it becomes unworkable when you cannot know the subclass type in advance, which I am working on right now. I'm adding plugin support. So the classes in the main bundle cannot know anything about the classes in the plugins.
I haven't found a way to store dynamic type in a variable, and I suspect that doing that would break the security anyway.
What I'm looking for... is a design pattern that incorporates all the flexibility of the Generically types array, but doesn't run afoul, Codable, while taking into account that I need to be able to add behavior and potentially variable to subclasses hosted in plugins, that will be required to be serialized in the Main bundle.
providing Codable support for a class. the class has an array that uses subclasses of the array's type. when you encode that sort of thing, you have to pull the array apart save individual arrays of each specific class, and then when you init that class, you will actually get the right Kind of type back.
it's a security thing. I get it.
but now... I have another wrinkle. the subclasses are going to be coming from plugins.
now I can't know in advance, what the total list of possible subclasses are.
what this all boils down to is:
I can ask a class what it's type is:
class.self
but can I capture that? I can't find the type for dynamicType.
I want to make an array of these types. I want to :
add a String Identifier to my plugin, and ask the plugin, for a string Identifier for the Type.
then I can save a dictionary of the subclasses, [String : [mySubClasses]]
the String would be : myPlugin.subClassHint
on Load, I should be able to cut up the string, I'll be able to find the plugin, and then ask for the type for that String...
but I need to be able to Set the return Type. dynamicType... doesn't work.
so, how do I refer to the dynamicType as a variable type? because... without it I've got no way to save data.
I have a protocol, in which I define a variable.public protocol CNEnvelopment {
var pan : CGPoint {get set}
var zoom : Float {get set}
var dagObjs : [CNDagObj] {get set} // this one.I use that protocol type coerce another type, to shield myself from having to test the object type, and write about 30 lines of code for the same behavior in a series of classes:(theParent as! CNEnvelopment).dagObjs.insert(contentsOf: droppedItems, at: theIndex + 1)but I get an error when I do that:Cannot use mutating member on immutable value of type '[CNDagObj]'do I need to just throw the protocol away and use a class? Because it will work properly if I make CNEnvelopment a class. is this a limitation of protocols?
updated to XCode 11.4then my app stopped compiling. this is the error:~/Library/Developer/Xcode/DerivedData/concrete-gbrhhoatnalnokezrxqmivnfpmuf/Build/Products/Debug/concrete.app: resource fork, Finder information, or similar detritus not allowedCommand CodeSign failed with a nonzero exit codeI'm fairly certain this error is not the real problem. my project has... 6 targets. 4 frameworks and desktop 2 applications. only happening to 1 application.I have cleaned all targets multiple times, tried rebooting, gone therough all targets and changed the names of folders named "Resources"logged out and back into my keychain, logged out and into of my account in XCode, turned off Signing altogether (or rather... I did the closest available thing,) changed the target OS version (started out at 10.14, went to 10.13, then 10.15)all random suggestions by random people on the internet.the app compiles, I can run it outside of Xcode. no problems. But it's not so finished that I can get by without actually debugging it.I've been through the project settings and compared them from the app that compiles and the app that ***** out. There's no obvious material difference.I think XCode is adding "resource fork, Finder information, or similar detritus" to my app, without my permission or my awareness.I'm at my wits end trying to track down the root cause for this compiler bug, that was inserted into my life with Xcode 11.4.help obi wan.-td
the docs are not helpful. in fact they don't seem to be indicating anything that works.so I'm hoping for a code example from someone who has been through this already.the context:I am writing a NSDraggingSource class. supporting the required method :func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation
// we would like to respond with move and copy.
let response : NSDragOperation = NSDragOperation.copy.rawValue | NSDragOperation.move.rawValue
return response
}
as I noted, I want to provide 2 supported drag types: move, and copy.the docs say to do this:If the source permits dragging operations, the elements in the mask are one or more of the constants described in Obtaining Information About the Dragging Session, combined using the C bitwise OR operator.C Bitwise OR Operator is documented to be "|"Apple does not provide any notable examples of using this in the real world. the few 3rd party examples I have found look like this:let result2 = inputA | inputB print("Result after applying | operator:",result2)/* resultResult after applying | operator: 7 */// note: that example is worthless in this context. I wind up with a cascade of opaque errors with unhelpful suggestions.this is not something that can be guessed. It needs to be documented. it needs to be clear, and have multiple examples. Real ones. Not integers. Barring that tho... has anyone been through this, and can provide a straightforward example?
I'm trying to find resources to learn how to render equirectangular output. basically a document that explains whatever would be in place of the camera view frustrum in a rendering pipeline. any help would be greatly appreciated.