__weak UIView * v = view;
[self moveView: v];
How can I write in swift?
__weak UIView * v = view; //Create weak var v that points to `view`
[self moveView: v]; //Call moveView using the new weak var
in Swift would be
weak var v: UIView? = view //Create weak var v that points to `view`
self.moveView(v) //Call moveView using the new weak var
or you might want to rename the function moveView to move(view:) to be more "Swifty"
Edit:
Note that based on a comment you made, it looks like your moveView(_:) function takes a non-optional variable. In that case, just get rid of the weak variable and pass in view directly:
self.moveView(view) //Call moveView using view directly
Related
I had a class UIBaseClassViewController with convenient functions in objective c.Now i'm switching to swift and i'm trying to convert it's code into swift.the function giving me problem is
+(UIBaseClassViewController*)getController
{
return [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:[NSBundle mainBundle]];
}
i was able to convert it but it's not working fine
static func getController() -> Self
{
print("sam controller class = \(String(describing:self))")
print("SAM controller = \(self.init(nibName: String(describing:self), bundle:Bundle.main))")
return self.init(nibName: String(describing:self), bundle:Bundle.main)
}
Output:
sam controller class = UILoginViewController
SAM controller = <Swift_And_Node.UIBaseClassViewController: 0x7f8a4ee13830>
created object is of type UIBaseClassViewController.it loads the nib fine but as object is of UIBaseClassViewController app crashes because it was not able to find functions in UIBaseClassViewController which are in UILoginViewController.
How can i make it create object of child class instead of parent.UILoginViewController in this case
for better Understanding showing adding code:
UIBaseClassViewController:
class UIBaseClassViewController: UIViewController {
static func getController() -> Self
{
print("sam controller class = \(String(describing:self))")
print("SAM controller = \(self.init(nibName: String(describing:self), bundle:Bundle.main))")
var object = self
return self.init(nibName: String(describing:self), bundle:Bundle.main)
}
}
UILoginViewController:
class UILoginViewController: UIBaseClassViewController {}
3rd controller who need UILoginViewController:
UILoginViewController.getController()
You either have to call this static function on desired view controller class or not making it static at all. Please see the example below to see how it works in Swift.
class ParentView: UIView {
static func printSelf() {
print(String(describing: self))
}
}
class ChildView: ParentView {}
ParentView.printSelf() // Prints ParentView
ChildView.printSelf() // Prints ChildView
Turns out we don't need to mention nib and bundle for controller object...I moved from objective c and these things are necessary there.
with
[[UILoginViewController alloc] init]
app will show black screen.
In swift we can just use UILoginViewController() and it will automatically associate nib with the controller object.
so to answer my question i just used
self.init()
instead of
self.init(nibName: String(describing:self), bundle:Bundle.main)
I'd like to use a delegate method written in Objective-C in Swift. The method is included in the MGSwipeTableCell framework (MGSwipeTableCell.h).
Objective-C:
-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion;
I try to convert it into Swift to and use the method:
func swipeTableCell(cell:MGSwipeTableCell, index:Int, direction:MGSwipeDirection, fromExpansion:Bool) -> Bool {
return true
}
But I don't know why but the function isn't getting called. Did I something wrong? I just want to get the indexPath of the swiped cell with this function.
You should implement MGSwipeTableCellDelegate protocol in your table view controller first. So you can just write:
class TableViewController : UITableViewController, MGSwipeTableCellDelegate {
....
....
....
func swipeTableCell(cell:MGSwipeTableCell, index:Int, direction:MGSwipeDirection, fromExpansion:Bool) -> Bool {
return true
}
}
and then when creating cells in cellForRowAtIndexPath: method you should create it like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let reuseIdentifier = "cell"
var cell = self.table.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
if cell == nil {
cell = MGSwipeTableCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
}
cell.delegate = self
return cell
}
Then you'll be able to track when swipe method is called because you set the cell delegate property.
It appears that the library you're trying to use has not adopted Objective-C nullability annotations yet, as such, any return values or arguments which are objects will be translated into Swift as implicitly unwrapped optionals (with the exclamation mark).
So, the signature you're looking for is this:
func swipeTableCell(cell: MGSwipeTableCell!, tappedButtonAtIndex: Int, direction: MGSwipeDirection, fromExpansion: Bool) -> Bool
But with that said, you need to add the protocol conformance anyway. If you do that first then try to write this method out, it should autocomplete to exactly how Swift expects it to look.
And then just make sure you're actually setting the cell's delegate property to whatever object is implement this method.
I am using both swift and objective-c in my app.
I have a CustomClass and I want to create a swift array for the class and add content to it from my objective-c class called oldClass that has an array of these objects in a NSArray called arrayOfCustomClass.
var newArray = [CustomClass]()
newArray += oldClass.arrayOfCustomClass
This causes an error:
'[(CustomClass)]' is not identical to 'CGFloat'
Any help?
thanks
Reza
The problem is that Swift knows nothing of what's in an NSArray. You must cast the NSArray explicitly to a [CustomClass] (and you'd better not be lying or you'll crash at runtime).
What seems to work is:
newArray += oldClass.arrayOfCustomClass as AnyObject as [CustomClass]
To do this safely you just need to try an optional cast. If you think the NSArray only has elements of type CustomClass, you can do this:
var newArray = [CustomClass]()
if let customArray = oldClass.arrayOfCustomClass as? [CustomClass] {
newArray += customArray
}
If you want to extract the CustomClass elements (a little different from what you asked, I know), this is the way:
var newArray = [CustomClass]()
for element: AnyObject in oldClass.arrayOfCustomClass {
if let custom = element as? CustomClass {
newArray.append(custom)
}
}
Sorry for a newbie question but can someone help with translating this to Swift?
-(instancetype)init
{
self = [super initWithImageNamed:#"character.png"];
{.
self.name = playerName;
self.zPosition = 10;
}
return self;
}
it's for a child of SKSpriteNode
When I try to call super.init(imageNamed: "character.png") I get an error saying `Must call a designated Initialiser of the superclass SKSpriteNode.
If I try to just write it like this:
init() {
super.init()
self.name = playerName
self.zPosition = 10
}
I get an error in my GameScene when I call:
var player : Player = Player(childNodeWithName(playerName))
I get an error about converting the type to string.
issue 1
a subclass initializer MUST call the superclass's designated Initializer.
for SKSpritenode that's initWithTexture: color: size:
SO
a SKTexture can be made from an image directly:
let texture = SKTexture(imageName: "character.png")
a color:
let color = UIColor.clearColor()
then:
super.init(texture: texture color:color size:texture.size)
issue 2:
class player needs an initialiser that takes a SKNode:
init(node: SKNode) {
...
}
I've a c function in my viewController.m.
int abc(int a, char* b)
{
//do something
}
I also have a function
-(void) callIncomingClass
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
button.frame = CGRectMake(100, 170, 100, 30);
//set the button's title
[button setTitle:#"Click Me!" forState:UIControlStateNormal];
//add the button to the view
[self.view addSubview:button];
}
Now I want to call callIncomingClass from within the function abc now.
How do you suggest I go about it??
Why I want to call an Objective C method from the C function is, I've cannot create a button or do some processing like that in the C function.
Should the following code work :
int abc(int a, char* b)
{
ViewController * tempObj = [[ViewController alloc] init];
[tempObj callIncomingClass];
}
edit : the big picture of what I am doing
There is a c library, i.e. a library.c and library.h file. The library.h file has a struct that has callback functions. These need to be assigned with function pointers. so I've a c function with the signature int abc(int,char*) that is to be assigned to the callback function in the struct.
This function abc is defined in ViewController.m.
Ideally i wanted it to be defined in a separate file. but this is also okie.
So now, the callback event happens, I want to create a UIButton with some action on the View. As I can't create a UIButton from a c function, i am calling a objective C method of the ViewController class, that creates the UIButton.
Hope that clears the picture as to how I am planning to use this.
Your button doesn't show because of what others and myself were saying: you need the existing instance of the ViewController. You are creating an entirely new instance of the ViewController, which is never brought on screen or pushed, etc.
You can accomplish what you need to do by using a global variable that points to your existing instance.
Here's what your .m should look like:
#import "ViewController.h"
static ViewController *viewController = nil;
#implementation ViewController
- (id)init {
if ((self = [super init])) {
viewController = self;
}
return self;
}
- (void)dealloc {
viewController = nil;
}
-(void) callIncomingCreateButton {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
button.frame = CGRectMake(100, 170, 100, 30);
//set the button's title
[button setTitle:#"Click Me!" forState:UIControlStateNormal];
//add the button to the view
[self.view addSubview:button];
}
- (IBAction)DemoCall:(id)sender {
callIncoming(1, "a");
}
#end
int callIncoming(int a, char* b) {
[viewController callIncomingCreateButton];
return a;
}
You need to get access to the correct ViewController* / instance, not any old one. If your C function signature doesn't let you pass in some arbitrary data via a void* or similar, then you need to use a class method, and a static variable to hold the temporary pointer as follows.
In your Objective C file:
static ViewController* cLibReceiver = NULL;
+(void) callIncomingClassOuter {
[cLibReceiver callIncomingClass];
}
-(void) beforeTriggerCLibrary {
cLibReceiver = self;
}
and in your (different) Objective C file with abc() in:
int abc(int a, char* b)
{
[ViewController callIncomingClassOuter];
}
Where you trigger the C Library, you need to do this:
[theViewController beforeTriggerCLibrary]; // could be self, depending on context
c_library_call();
// optionally set cLibReciever back to NULL.
note: I may have got some of the syntax wrong on method headers etc, I'm not entirely familiar with objective C calling conventions. class methods are definitely + though.
note 2: you may not be allowed to extend the system class like this - you may need to define your own subclass. Again, not familiar enough with Objective C.
Assuming that you are in an Objective-C source file, calling an Objective-C function from a C function works exactly the same as calling the Objective-C function from any other Objective-C function. In either case, if you have a pointer ptr to the object that you want to call the function on, you write
[ptr callIncomingClass];
so of course in either case you need to somehow have the pointer to the object you want to call the function on. If you are in an Objective-C function (i.a. an instance method) the usual "source" for such pointers are (a) the implicit "self" pointer when you are calling a method on the same object as the currently running methid, (b) some instance-variable of the object on which the currently running method was called, (c) an argument to the currently running function or method, (d) a global variable or the result of some other function call. In plain C you can use (c) and (d), but not (a) and (b) because you don't have a self.