Making UIBezierPath more like NSBezierPath with elementCount and elementAtIndex - iphone

When moving some Cocoa code to Cocoa Touch I was disappointed to find that UIBezierPath is missing the "Accessing Elements of a Path" methods:
– elementCount
– elementAtIndex:
– elementAtIndex:associatedPoints:
– removeAllPoints
– setAssociatedPoints:atIndex:
The only way to get at these elements in Cocoa Touch seems to be through CGPathApply. Before I try to recreate this as a subclass or category of UIBezierPath, I was wondering if this had already been done. Does anyone have an idea if something like this is already available?

I made a port on https://github.com/seivan/UIBezierPathPort but it's with Swift.
Has a test suite and documentation.
Works as of Beta 5.
Technically you should be able to use Swift on a Obj-C project.
Let me know how you like it.

I've bumped into the same problem a couple of months ago and couldn't find anything readily available back then. (Truth be told, since going the CGPathApply route wasn't that bad for my needs, I didn't look very hard to be honest).
The applier function is called for every CGPathElement in the CGPath, such an element consists of a CGPathElementType and a C-array of CGPoints.
Since a CGPathElementType is an enum with only five different values
enum CGPathElementType {
kCGPathElementMoveToPoint,
kCGPathElementAddLineToPoint,
kCGPathElementAddQuadCurveToPoint,
kCGPathElementAddCurveToPoint,
kCGPathElementCloseSubpath
};
You don't need to write that much code to do (control)point manipulation / inspection of a path. Having the same interface available would've been nice though.

Related

GKRTree doesn't want to work at all, any other similar method?

I'm making a game, where i need to define the object in the radius of the explosion in certain radius. Firstly, i was making it through distance between all objects, but i saw that there is GKRTree class in GameplayKit. But after many tries, it doesn't want to work at all. It just returns empty array in any case. I want to know, are GKRTree class broken or what. If yes, are there any other method to do the same stuff as GKRTree in swift or github. Because i dont want to calculate distance, since it can be use a lot of cpu.
Thanks
Edit: I tried what is described in this answer https://stackoverflow.com/a/38655862/11687591, but it dont work. And there are no another solution about this problem. There is some links, where somebody is talking about broken gkrtree and there is no answer. https://www.reddit.com/r/swift/comments/63frk6/does_anyone_have_a_working_example_of_gkrtree/
https://twitter.com/StayOnTheMove/status/1067067053419520000?s=20
And that's all. One things that i've tried that i created 2 circles. One of them is not moving and in one position all the time. Another is moving to my touch position. Second is smaller than the other one. Larger is a little bit transparent so i can see other circle. I also use print() to see all things that happening in the code. And after all of that, even if there is clearly situation where one circle is inside other one, gkrtree.entities method don't work and it returns empty array.
For what it's worth, GamePlayKit.GKRTree is recently failing for me as of Xcode 11.5+. The following line,
import GameKit
class blah {
private var searchTree: GKRTree<RouteSegment>?
public init() {
searchTree = GKRTree.init(maxNumberOfChildren: 3)
}
}
Using a let expression also gets a nil value.
Edit:
The reason it was returning nil is because I didn't have GameplayKit in the linking phase of the project. Duh. By default, all the iOS frameworks are on the search path, which doesn't mean they will be available at runtime. I'm not sure why Apple chose this mechanism. When I traced the assembly code step into the init() function, I found it just returned nil; there must be some stubs in the API.
Solution for me: make sure that GameplayKit is in the linked binaries phase in the project settings.

Swift 3 (Omit Needless Words) causing two functions to have the same name

In Swift 3.0, the automated changing of function names due to the "Omit Needless Words" rule has caused two functions in an ObjC class to be the same.
- (void)showLoader;
...and...
- (void)show __deprecated_msg("User 'showLoader'");
The problem is that these functions are within a third party Cocoa Pod (otherwise I would just delete the unnecessary 'show' function).
This results in getting the error "Ambiguous use of 'show'" when I try to invoke the function like this:
loader?.show()
Is there a way to reverse the automatic changing of function name in Swift 3.0 or to help the compiler know which function I want to invoke?
Thanks for your help!
See MartinR's answer to my similar question here: Converting to Swift 3 renamed my own Objective-C method
If you owned the code, you could use NS_SWIFT_NAME(showLoader()) after your method declaration to force the ObjC-to-Swift method conversion to be named what you want:
- (void)showLoader NS_SWIFT_NAME(showLoader());
I think it's worth mentioning even though in your case it doesn't exactly solve your problem because you don't own the code.
You can work around this by calling
loader?.perform(Selector("showLoader"))
You will see a warning from the compiler, but it will compile successfully, and things will work correctly at runtime.

NSTextStorage easily / background attribute change

I'm finishing a nice app with a relatively small text editor. During implementation of the syntax highlight I found myself in need to change foreground colour attribute of recognized tokens. I noticed that there is a property of NSTextStorage:
var fixesAttributesLazily: Bool { get }
The documentation, regarding it is:
A Boolean value indicating whether the text storage object fixes attributes lazily. (read-only)
Discussion
When subclassing, the default value of this property is NO, meaning that your subclass fixes attributes immediately when they are changed. The system’s concrete subclass overrides this property and sets it to YES.
I really don't know how to interpret this ... but this is what I did:
I'm changing the attributes of th recognised tokens inside textStorage(textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int) (which is a delegate method of NSTextStorage). Here I'm checking the value of this property - it's FALSE.
I subclassed NSTextStorage exactly as Apple suggest (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/Subclassing.html) and overrode the property. The text view started to behave very strange. Actually with small text it performs OK, but as soon as I open a 4 Mbytes file - it hangs and ... well ... bad things start to happen to my mac. Actually this behaviour doesn't depend on the value of the fixesAttributesLazily property. Maybe my implementation of NSTextStorage is bad or at least not sophisticated.
Any trick of applying attributes in background or lazily or ... something like this is welcomed.
In additional: I know that there are many ways to optimise a syntax highlighted. It may highlight partially, use some kind of logic, based on the changed range ... etc. What I'm looking for is a way to process attribute changes in background. For example currently when I paste 4 Mbyte file to the text view, it first highlights it (which takes 2-3 seconds) and then it visualises it. The effect I'm looking for is the text to appear right away and after time - the colors.
The project I'm working on is written in Swift.
Thanks to everyone in advance for the help. You may reach me via ivailon at gmail dot com for specifics, since I don't want to expose the app here ... at least not yet ;-)

Xcode 4.6, used as the name of the previous parameter rather than as part of the selector [duplicate]

This question already has answers here:
Error after upgrading to xcode 4.6 and iOS 6.1 "used as the name of the previous parameter rather than as part of the selector"
(3 answers)
Closed 10 years ago.
I'm getting the following warning from Xcode 4.6.
.. used as the name of the previous parameter rather than as part of the selector
I know I can disable this warning, but I'd rather fix it.
I have 109 such warnings, so I'm obviously writing methods badly.
Here's a couple of my methods.
+(NSString*)addFormatPrice:(double)dblPrice:(BOOL)booRemoveCurSymbol;
-(void)showHelpChoices:(UIView *)vw:(id)dg;
So, whats the correct way to write these methods ?
Your first method is declaring the selector +addFormatPrice::. With spaces, it looks like
+ (NSString *)addFormatPrice:(double)dblPrice :(BOOL)booRemoveCurSymbol;
This is invoked like [NSString addFormatPrice:0.3 :YES].
What you should do is actually give a name to the previous parameter, such as
+ (NSString *)addFormatPrice:(double)dblPrice removeCurSymbol:(BOOL)booRemoveCurSymbol;
Which would then be invoked like [NSString addFormatPrice:0.3 removeCurSymbol:YES].
Maybe you'll have an easier time understanding if you split these across several lines?
+(NSString*)addFormatPrice:(double)dblPrice
:(BOOL)booRemoveCurSymbol;
-(void)showHelpChoices:(UIView *)vw
:(id)dg;
An Objective-C method name's structure is like this:
- (returntype)firstPartOfMethodWithParameter:(type)nameOfFirstParameter secondPartOfNameWhichDescribesSecondParameter:(type)nameOfSecondParameter;
That is, the full method name is broken up, with the parameter names interspersed. The colons separate each "label" from its parameter; a space separates the parameter name from the next part of the method name.
Your methods are missing the second parts, the bits that describe the second parameters. Right now, the names of your methods are addFormatPrice:: and showHelpChoices::, both of which are legal but un-idiomatic. When you call them, it will look like this:
[Excelsior addFormatPrice:2.0 :YES];
[thumpy showHelpChoices:aView :obj];
which should make it clear that your names aren't quite right. You just need to add the labels for the second parameters:
+(NSString*)addFormatPrice:(double)dblPrice
removingCurrencySymbol:(BOOL)booRemoveCurSymbol;
-(void)showHelpChoices:(UIView *)vw
digeridoo:(id)dg;
For advice on naming Objective-C methods, you should turn to an Objective-C style guide such as Apple's coding guidelines for Cocoa. Any style guide that follows the conventions of the community and Apple's frameworks will suggest that you name your method such that the purpose of each parameter is clearly described within the method name.
+(NSString *)priceStringWithPrice:(double)price removeCurrencySymbol:(BOOL)removeCurrencySymbol
-(void)showHelpChoicesInView:(UIView *)view withSomethingWithAnUndecipherableName:(id)mysteryParameter
Notice the significant change in name to indicate what (I assume) it does in your program and what each parameter does. Your class method doesn't add anything to anything - rather it returns a new string. This makes your code blend naturally with that of other developers, Apple's frameworks, other libraries you may use, and enhances the readability greatly. Not naming your parameters degrades readability and makes maintainability far more difficult.
On a related note, unnecessary abbreviations, including Hungarian notation, are jarring and don't fit the style, and if you follow good naming practices you don't need them and will produce code that is a pleasure to maintain. So don't call it vw, call it view or viewToShowIn. Don't call it strVal call it valueString or somethingSpecificallyDescribingTheNatureOfTheValueString.
This is how you are supposed to do this
+(NSString*)addFormatPrice:(double)dblPrice removeCurSymbol:(BOOL)booRemoveCurSymbol;
-(void)showHelpChoices:(UIView *)vw whatEverThePurposeOf:(id)dg;
try to learn from Apple's example code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
for start, you can try to write your method in a sentence.
like this
applicationdidFinishLaunchingWithOptions
then, add the noun description with parameters like (UIApplication *)application and (NSDictionary *)launchOptions

What is scala.mobile supposed to accomplish?

...and why has the package this misleading name (I assumed it had something to do with JavaME or mobile/smart phones)?
I found no references on the internet about scala.mobile.Code or scala.mobile.Location at all nor did I manage to do anything with those classes except getting ClassCastExcetions or NoSuchMethodErrors.
Actually there is not even a single test against scala.mobile in the Scala's test tree which could help understanding that code.
The classes really smell like they were forgotten in the source tree a long time ago and got accidentally released since that.
Maybe I just missed something about them?
Update:
scala.mobile was removed in Scala 2.9.
I just checked the source code.
When Scala changed the name mangling of class files a few years ago and it seems people forgot to update these classes accordingly.
So my answer would be:
At least Location has no purpose, because it is not possible to get anything sensible out of it (except exceptions) and Code without Location is severely limited. It works though if you pass the class literal to Code directly:
import scala.mobile._
val c = new Code(classOf[scala.collection.mutable.StringBuilder])
c.apply[StringBuilder, String]("append")("Foo")
c.apply[String]("toString")() // returns "Foo"
c.apply[Int]("length")() // returns 3
Looks like yet-another implementation in the standard library of reflection-slightly-nicer.
The description of Location pretty much explains what that is about:
The class Location provides a create method to instantiate objects
from a network location by specifying the URL address of the jar/class file.
It might be used by remote actors. Maybe.
As for why it has this misleading name? Well, back in 2004 smart phones had really low penetration, so maybe the association wasn't all that strong.