强制用户使用自定义init方法进行初始化

时间:2017-07-17 12:32:16

标签: ios swift

我正在创建一个public class AddDriverStateDialog extends DialogFragment { private static AddDriverStateDialog addDriverStateDialog; // Data references private int DRIVER_STATE = 0; private final String[] items = {"On Duty", "Off Duty", "Sleeper", "Driving","Yard Move","Personal Conveyance"}; private ItemAdapter itemAdapter; // UI References private View view; private RadioRealButtonGroup radioButtonGroup; private EditText note,edittime; Calendar calendar; private MainActivity mainActivity; public static AddDriverStateDialog newInstance(MainActivity mainActivity) { if (addDriverStateDialog == null) { addDriverStateDialog = new AddDriverStateDialog(); } addDriverStateDialog.mainActivity = mainActivity; return addDriverStateDialog; } @Override public void onResume() { ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes(); params.width = ViewGroup.LayoutParams.MATCH_PARENT; getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); super.onResume(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Initialise UI elements view = LayoutInflater.from(mainActivity).inflate(R.layout.dialog_add_driver_state, null); radioButtonGroup = (RadioRealButtonGroup) view.findViewById(R.id.radioGroup_dialog_addDriverState_driverStates); note = (EditText) view.findViewById(R.id.et_dialog_addDriverState_note); //edittime= (EditText)view.findViewById(R.id.et_dialog_addDriverState_time); calendar = Calendar.getInstance(); // UI Interaction listeners /* Driver State Selection Listener */ radioButtonGroup.setOnClickedButtonListener(new RadioRealButtonGroup.OnClickedButtonListener() { @Override public void onClickedButton(RadioRealButton button, int position) { switch (button.getId()) { case R.id.radioBtn_dialog_addDriverState_offDuty: DRIVER_STATE = DriverState.STATE_OFFLINE; break; case R.id.radioBtn_dialog_addDriverState_onDuty: DRIVER_STATE = DriverState.STATE_ONLINE; break; case R.id.radioBtn_dialog_addDriverState_sleeperBerth: DRIVER_STATE = DriverState.STATE_SLEEPER; break; case R.id.radioBtn_dialog_addDriverState_driving: DRIVER_STATE = DriverState.STATE_DRIVING; break; case R.id.radioBtn_dialog_addDriverState_yard_move: DRIVER_STATE = DriverState.STATE_YARD_MOVE; break; case R.id.radioBtn_dialog_addDriverState_personal_conveyance: DRIVER_STATE=DriverState.STATE_PERSONAL_CONVEYANCE; break; } } }); } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(mainActivity) .setTitle("Add Event") .setCancelable(false) .setView(view) .setPositiveButton("Log Event", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mainActivity.updateDashboard(DRIVER_STATE, note.getText().toString()); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dismiss(); } }) .create(); } } 子类,目的是强制用户使用我所需的init方法而不是默认方法。

为此,我为此创建了一种方便的方法。

UIView

这个有效!但是,当我尝试@available(*, unavailable, message: "init is unavailable.") public override init(frame: CGRect) { super.init(frame: frame) } required convenience public init(withSomeParameters myParam:Type) { self.init(frame: CGRect.zero) //Doing something nice! } 时,它会向我展示两种初始化方法。如何强制用户使用自定义init方法?

2 个答案:

答案 0 :(得分:4)

您可以将其设为私有,因此用户必须使用withSomeParameters

初始化Test类
class Test:UIView {
    private override init(frame: CGRect) {
        super.init(frame: frame)
    }

    convenience public init(withSomeParameters myParam:Type) {
        self.init(frame: CGRect.zero)
        //Doing something nice!
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

答案 1 :(得分:0)

也许您需要将编码器初始化程序标记为不可用:

@available(*, unavailable)
  required init?(coder aDecoder: NSCoder) {
  super.init(coder: aDecoder)
}

加:从初始化程序中删除convenience,然后调用超级init(frame:)

public init(withSomeParameters myParam:Type) {
  super.init(frame: .zero)
  //Doing something nice!
}

作为另一个例子,这里有一些基础UIView子类我在很多不利用故事板的项目中使用:

class MXView: UIView {
  init() {
   super.init(frame: .zero)
  }

  //  Storyboards are incompatible with truth and beauty.
  @available(*, unavailable)
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }
}

子类:

class CustomView: MXView {
  init(someParameters params: Type) {
    // Phase 1: store ivars.

    super.init()

    // Phase 2: Do something nice.
}

如果你这样做,CustomView的用户将被迫使用init(someParamters:)init(frame:)被遮蔽,因为init(someParameters:)是非便利初始化。