I am facing issues while converting from Objective C to Swift 2.2.. Can anyone help me..??
Here is the code in Objective C
variables declared as
#property (nonatomic, assign) NSInteger currentViewControllerIndex;
#property (nonatomic, getter = isWrapEnabled) BOOL wrapEnabled;
and the variable setting functions in Objective C are
- (void)setWrapEnabled:(BOOL)sWrapEnabled {
wrapEnabled = sWrapEnabled;
[self.view layoutIfNeeded];
}
- (void)setCurrentViewControllerIndex:(NSInteger)curViewControllerIndex {
[self scrollToViewControllerAtIndex:curViewControllerIndex animated:NO];
}
This is how i have written in Swift
var tmpWrapEnabled : Bool = Bool()
internal(set) var wrapEnabled : Bool? {
get {
return tmpWrapEnabled
}
set(newValue) {
if newValue == true {
tmpWrapEnabled = newValue!
self.view.layoutIfNeeded()
}
}
}
var tmpCurrentViewControllerIndex : NSInteger = 0
internal(set) var currentViewControllerIndex : NSInteger? {
get {
return tmpCurrentViewControllerIndex
}
set(newValue) {
tmpCurrentViewControllerIndex = newValue!
}
}
Basically you need only the didSet observers, for the rest the variable behaves as a normal variable.
var wrapEnabled : Bool {
didSet {
if wrapEnabled {
self.view.layoutIfNeeded()
}
}
}
var currentViewControllerIndex : Int {
didSet {
scrollToViewControllerAtIndex(currentViewControllerIndex, animated:false)
}
}
Consider that the observers are not called when the initial value is assigned to the variable.
Related
I have a problem with get property. When I pass _videoRect to the drawArea function that nothing happens. But if I am change self.videoRect that work perfect.
My code:
#property (nonatomic, assign) BOOL isRecording;
#property (nonatomic) NSValue* videoRect;
#implementation Interactor
#synthesize videoRect = _videoRect;
- (id)init {
_isRecording = NO;
[self createVideoObserver];
return self;
}
- (void)record {
_isRecording = !_isRecording;
if (!_isRecording) {
[self stop];
[_presenter animateRecordButton:_isRecording];
} else {
[self drawArea:&(_videoRect) completion:nil];
}
}
- (void)drawArea:(NSValue* __strong *)rect completion:(void (^ __nullable)(void))completion {
if (!_isFullScreen) {
*rect = [NSValue valueWithRect:[self fullScreenRect]];
} else {
[self drawScreenRect];
}
if (completion != NULL) {
completion();
}
}
Setter and getter:
- (void)setVideoRect:(NSValue*)videoRect {
_videoRect = videoRect;
}
- (NSValue*)videoRect {
return _videoRect;
}
Create video observer:
- (void)createVideoObserver {
[[RACObserve(self, videoRect) skip:1] subscribeNext:^(id _) {
[self start];
[_presenter animateRecordButton:_isRecording];
}];
}
I don’t understand why observer doesn’t work. How can I pass self.videoRect to the drawArea function?
Your -drawArea:completion: method is taking a pointer to an NSValue, whereas self.videoRect is a property to an NSValue. In Swift, you can pass a property like this by reference, but in Objective-C, a property is really nothing more than a couple of methods, one of which sets an instance variable and one which returns it. So just passing the property into the method will not work. What you need to do is to read the property, pass a pointer to the resulting value, and then modify the property with the new value:
NSValue *videoRect = self.videoRect;
[self drawArea:&videoRect completion:^{
...
self.videoRect = videoRect;
}];
I am trying to make a swift 3 struct conform to _ObjectiveCBridgeable but I am not sure what else I need to satisfy the protocol. Below is my struct and the _ObjectiveCBridgeable conformance. I am missing something but I am not sure what it is.
struct Box {
let contents: Any
}
extension Box: _ObjectiveCBridgeable {
typealias _ObjectiveCType = thing;
init(fromObjectiveC source: _ObjectiveCType) {
contents = source.contents
}
static func _isBridgedToObjectiveC() -> Bool {
return true
}
static func _getObjectiveCType() -> Any.Type {
return _ObjectiveCType.self
}
func _bridgeToObjectiveC() -> Box._ObjectiveCType {
return thing(contents: self.contents)
}
static func _forceBridgeFromObjectiveC(_ source: Box._ObjectiveCType, result: inout Box?) {
result = Box(contents: source.contents)
}
static func _conditionallyBridgeFromObjectiveC(_ source: Box._ObjectiveCType, result: inout Box?) -> Bool {
_forceBridgeFromObjectiveC(source, result: &result)
return true
}
}
// Objc
#interface thing : NSObject
#property (readonly) id contents;
-(instancetype)initWithContents:(id)contents;
#end
#implementation thing
- (instancetype)initWithContents:(id)contents {
if ((self = [super init])) {
_contents = contents;
}
return self;
}
#end
As the underscore tells you, _ObjectiveCBridgeable is private. Its purpose is "to accommodate the specific needs of bridging Objective-C object types to Swift value types". You cannot adopt it for your own types; it works by means of "compiler magic under the hood".
There is a proposal on the table to provide a public version, but it has not yet been implemented.
What will be the syntax of the following Objective-C method in Swift?
-(id)init
{
Viewcontroller static *vc=nil;
if(!vc)
{
vc=[super init];
return vc;
}
else return vc;
}
Below is the syntax in Swift 3
override init() {
var vc: Viewcontroller? = nil
if vc == nil {
vc = super.init()
return vc!
}
else {
return vc!
}
}
I'm trying to change the text of a button once it is pressed however it doesn't work. Am i missing something?
i've been trying to figure my problem for hours.
any help would be appreciated.
h. file
#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>
#interface InterfaceController : WKInterfaceController
{
IBOutlet WKInterfaceButton*playpausebtn;
}
-(IBAction)play;
#end
m. file
#import "InterfaceController.h"
#import <WatchConnectivity/WatchConnectivity.h>
#interface InterfaceController() <WCSessionDelegate>
#end
#implementation InterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
// Configure interface objects here.
}
- (void)willActivate {
[super willActivate];
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
-(IBAction)play{
[playpausebtn setTitle:#"sleep"];
}
It is working fine in Swift-3 Xcode-8.1 .
// InterfaceController.swift
// WatchKit Extension
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController,WCSessionDelegate {
#IBOutlet var textLabel: WKInterfaceLabel!
var session:WCSession?
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
checkSupportOfSession()
changeAttributeOfText()
}
#IBOutlet var buttonOutlet: WKInterfaceButton!
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
func checkSupportOfSession() {
if( WCSession.isSupported() ) {
self.session = WCSession.default()
self.session?.delegate = self
self.session?.activate()
}
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("session")
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
let message:String = message["textIndex"] as! String
textLabel.setText(message)
print(message)
}
func changeAttributeOfText() {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
let font = UIFont.boldSystemFont(ofSize: 12)
let attributes:Dictionary = [NSParagraphStyleAttributeName:paragraphStyle , NSFontAttributeName:font ]
let attributeString:NSAttributedString = NSAttributedString(string: "HELLO", attributes: attributes)
textLabel.setAttributedText(attributeString)
}
//Change the ButtonTitle after click
#IBAction func buttonClicked() {
buttonOutlet.setTitle("textNew")
}}
Demo App
I have a function in swift as follows
public class XYZ:NSObject {
public static func getInstance() -> GlobalEventBus {
return globalEventBusInstance
}
public static var xyzInstance:XYZ = XYZ()
var initialized:Bool?
public func dispatchEvent(customEvent:CustomEvent) { }
override init() {
initialized = true
}
}
I used the getInstance function in objective C implementation as follows
#implementation SomeFile
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
/* log a message */
- (void)sendEvent:(CDVInvokedUrlCommand*)command
{
id message = [command argumentAtIndex:0];
XYZ *xyzInstance = [XYZ getInstance];
CustomEvent *customEvent = [CustomEvent alloc];
xyzInstance.dispatchEvent(customEvent)
//customEvent.eventType =
}
#end
The problem i am seeing is that I see an error
"Property dispatchEvent not found on object of type XYZ *"
Does it have anything to do with the fact that the instance variable being returned is a static variable? What am I doing wrong? Please help
Thank you
Nikhil
In your Objective-C code, you have a line that says:
xyzInstance.dispatchEvent(customEvent)
That's Swift. You want:
[xyzInstance dispatchEvent:customEvent];